From ca3fd7971e9e9c95a5b573aafb08060d8087db15 Mon Sep 17 00:00:00 2001 From: kami Date: Fri, 3 Jul 2026 01:01:04 +0400 Subject: [PATCH] fix(server): skip an unmappable event on replay instead of tearing down the stream Wrap the per-event mapper.map in runCatching in the replay loop so a single event the mapper can't handle no longer kills the whole WebSocket stream. Defense-in-depth beyond the AnyMapSerializer fix. --- .../com/correx/apps/server/ws/SessionStreamHandler.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/server/src/main/kotlin/com/correx/apps/server/ws/SessionStreamHandler.kt b/apps/server/src/main/kotlin/com/correx/apps/server/ws/SessionStreamHandler.kt index 5e3a8abd..4c07d411 100644 --- a/apps/server/src/main/kotlin/com/correx/apps/server/ws/SessionStreamHandler.kt +++ b/apps/server/src/main/kotlin/com/correx/apps/server/ws/SessionStreamHandler.kt @@ -31,9 +31,12 @@ class SessionStreamHandler(private val module: ServerModule) { log.debug("replaying {} event(s) for session={}", replayEvents.size, sessionId.value) for (event in replayEvents) { - mapper.map(event)?.let { msg -> - session.send(Frame.Text(ProtocolSerializer.encodeServerMessage(msg))) - } + runCatching { mapper.map(event) } + .onFailure { log.warn("skipping unmappable event seq={}: {}", event.sequence, it.message) } + .getOrNull() + ?.let { msg -> + session.send(Frame.Text(ProtocolSerializer.encodeServerMessage(msg))) + } } module.approvalCoordinator.registerClient(sessionId, session)