From 2ad6aa6c1efb492a8a22f1c61e81b2c0105c7661 Mon Sep 17 00:00:00 2001 From: Florent Clairambault Date: Sun, 11 Jan 2026 20:54:31 +0100 Subject: [PATCH] fix: handle closed connection errors gracefully When a client disconnects immediately after connecting (before sending any commands), the server would log multiple error messages: - "Network error" from SetDeadline - "Network error" or "Read error" from ReadLine This change detects "use of closed network connection" and "connection reset by peer" errors and handles them as normal disconnects instead of errors. This reduces log noise and provides clearer debugging info. The fix addresses two code paths: 1. In readCommand(): Check if SetDeadline fails due to closed connection and return early instead of trying to read 2. In handleCommandsStreamError(): Treat closed connection errors as normal disconnects (debug level) instead of errors Fixes #710 Co-Authored-By: Claude Opus 4.5 --- client_handler.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/client_handler.go b/client_handler.go index 18484e71..1c0c3d99 100644 --- a/client_handler.go +++ b/client_handler.go @@ -451,6 +451,15 @@ func (c *clientHandler) readCommand() bool { if c.server.settings.IdleTimeout > 0 { if err := c.conn.SetDeadline( time.Now().Add(time.Duration(time.Second.Nanoseconds() * int64(c.server.settings.IdleTimeout)))); err != nil { + // If the connection is already closed, return early instead of trying to read + if isClosedConnError(err) { + if c.debug { + c.logger.Debug("Client disconnected before first command") + } + + return true + } + c.logger.Error("Network error", "err", err) } } @@ -525,11 +534,29 @@ func (c *clientHandler) handleCommandsStreamError(err error) bool { return true } + // Check if this is a closed connection error - treat as normal disconnect + if isClosedConnError(err) { + if c.debug { + c.logger.Debug("Client disconnected", "clean", false) + } + + return true + } + c.logger.Error("Network error", "err", err) return true } + // Check for closed connection errors before logging as error + if isClosedConnError(err) { + if c.debug { + c.logger.Debug("Client disconnected", "clean", false) + } + + return true + } + if errors.Is(err, io.EOF) { if c.debug { c.logger.Debug("Client disconnected", "clean", false)