From dd1cdeca9457d59426bd6425871d71b5898602a7 Mon Sep 17 00:00:00 2001 From: Santhosh Date: Sat, 25 Jul 2026 11:32:07 +0000 Subject: [PATCH 1/2] Improve error propagation in server bind, polling disconnect, and websocket writes Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../java/com/socketio4j/socketio/SocketIOServer.java | 6 ++++-- .../socketio4j/socketio/handler/EncoderHandler.java | 11 ++++++----- .../socketio/transport/PollingTransport.java | 5 +++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/SocketIOServer.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/SocketIOServer.java index 0d3a6561..df148a82 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/SocketIOServer.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/SocketIOServer.java @@ -608,8 +608,10 @@ public Future startAsync() { int actualPort = local.getPort(); configCopy.setPort(actualPort); configuration.setPort(actualPort); - } catch (Exception ignore) { + } catch (Exception e) { // keep configured port if localAddress is not InetSocketAddress + log.debug("Could not resolve actual bound port, keeping configured port {}", + configCopy.getPort(), e); } } serverStatus.set(ServerStatus.STARTED); @@ -618,7 +620,7 @@ public Future startAsync() { fireAfterStart(); } else { serverStatus.set(ServerStatus.INIT); - log.error("Failed to start server on port {}", configCopy.getPort()); + log.error("Failed to start server on port {}", configCopy.getPort(), future.cause()); cleanUpResources(false); } }); diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/EncoderHandler.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/EncoderHandler.java index 2ad090c4..f88a50a0 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/EncoderHandler.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/EncoderHandler.java @@ -111,8 +111,9 @@ private void readVersion() throws IOException { version = name + "/" + attrs.getValue("Bundle-Version"); break; } - } catch (IOException E) { - // skip it + } catch (IOException e) { + // A single unreadable manifest must not prevent reading the others + log.debug("Skipping unreadable MANIFEST.MF while resolving version header", e); } } } @@ -304,7 +305,7 @@ private void handleWebsocket(final OutPacketMessage msg, ChannelHandlerContext c ByteBuf dstStart = out.readSlice(FRAME_BUFFER_SIZE); dstStart.retain(); WebSocketFrame start = new TextWebSocketFrame(false, 0, dstStart); - ctx.channel().write(start); + writeFutureList.add(ctx.channel().write(start)); int fragmentCount = 1; while (out.isReadable()) { @@ -312,7 +313,7 @@ private void handleWebsocket(final OutPacketMessage msg, ChannelHandlerContext c ByteBuf dst = out.readSlice(re); dst.retain(); WebSocketFrame res = new ContinuationWebSocketFrame(!out.isReadable(), 0, dst); - ctx.channel().write(res); + writeFutureList.add(ctx.channel().write(res)); fragmentCount++; } @@ -328,7 +329,7 @@ private void handleWebsocket(final OutPacketMessage msg, ChannelHandlerContext c out.readableBytes(), msg.getSessionId()); } WebSocketFrame res = new TextWebSocketFrame(out); - ctx.channel().writeAndFlush(res); + writeFutureList.add(ctx.channel().writeAndFlush(res)); } else { if (log.isDebugEnabled()) { log.debug("Empty packet, releasing buffer, sessionId: {}", msg.getSessionId()); diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/transport/PollingTransport.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/transport/PollingTransport.java index 1e34aeae..f5524c69 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/transport/PollingTransport.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/transport/PollingTransport.java @@ -128,6 +128,11 @@ private void handleMessage(FullHttpRequest req, UUID sessionId, QueryStringDecod String origin = req.headers().get(HttpHeaderNames.ORIGIN); if (queryDecoder.parameters().containsKey("disconnect")) { ClientHead client = clientsBox.get(sessionId); + if (client == null) { + log.error("{} is not registered. Closing connection", sessionId); + sendError(ctx); + return; + } client.onChannelDisconnect(); ctx.channel().writeAndFlush(new XHRPostMessage(origin, sessionId)); } else if (HttpMethod.POST.equals(req.method())) { From 8f0ea9ea569f632d1ed19dcf57db8c1c81620968 Mon Sep 17 00:00:00 2001 From: Santhosh Date: Sat, 25 Jul 2026 11:42:11 +0000 Subject: [PATCH 2/2] Revert websocket ChannelFutureList change per review feedback Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../com/socketio4j/socketio/handler/EncoderHandler.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/EncoderHandler.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/EncoderHandler.java index f88a50a0..2aaf4a3d 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/EncoderHandler.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/EncoderHandler.java @@ -305,7 +305,7 @@ private void handleWebsocket(final OutPacketMessage msg, ChannelHandlerContext c ByteBuf dstStart = out.readSlice(FRAME_BUFFER_SIZE); dstStart.retain(); WebSocketFrame start = new TextWebSocketFrame(false, 0, dstStart); - writeFutureList.add(ctx.channel().write(start)); + ctx.channel().write(start); int fragmentCount = 1; while (out.isReadable()) { @@ -313,7 +313,7 @@ private void handleWebsocket(final OutPacketMessage msg, ChannelHandlerContext c ByteBuf dst = out.readSlice(re); dst.retain(); WebSocketFrame res = new ContinuationWebSocketFrame(!out.isReadable(), 0, dst); - writeFutureList.add(ctx.channel().write(res)); + ctx.channel().write(res); fragmentCount++; } @@ -329,7 +329,7 @@ private void handleWebsocket(final OutPacketMessage msg, ChannelHandlerContext c out.readableBytes(), msg.getSessionId()); } WebSocketFrame res = new TextWebSocketFrame(out); - writeFutureList.add(ctx.channel().writeAndFlush(res)); + ctx.channel().writeAndFlush(res); } else { if (log.isDebugEnabled()) { log.debug("Empty packet, releasing buffer, sessionId: {}", msg.getSessionId());