fix(gateway): replace socket.once with socket.on for error handling

When a WebSocket client drops off the network, the underlying TCP
socket may emit multiple consecutive 'error' events (e.g., EPIPE,
ECONNRESET) as the server attempts to flush buffered writes.

Using socket.once('error', ...) only handled the first error event.
Subsequent errors had no handler and caused Node.js to throw an
uncaught ERR_UNHANDLED_ERROR, crashing the gateway process.

Using socket.on('error', ...) handles all error events. The close()
callback is already idempotent (guarded by a closed flag at line 173),
so multiple invocations are safe.

Reproduces on v2026.2.26 with any client that drops the TCP connection
while the server has pending writes (heartbeats, in-flight messages).

Fixes #12354
This commit is contained in:
Ash (Bug Lab) 2026-02-27 19:18:06 +08:00
parent 8a05c05596
commit 543f296e34

View File

@ -194,7 +194,7 @@ export function attachGatewayWsConnectionHandler(params: AttachGatewayWsConnecti
}
};
socket.once("error", (err) => {
socket.on("error", (err) => {
logWsControl.warn(`error conn=${connId} remote=${remoteAddr ?? "?"}: ${formatError(err)}`);
close();
});