{"record":{"id":"08154f8d89a3e9c9","repo":"valeriansaliou/sonic","slug":"closing-channel","errorCode":null,"errorMessage":"closing channel","messagePattern":"closing channel","errorType":"panic","errorClass":"panic","httpStatus":null,"severity":"error","filePath":"server/src/channel/handle.rs","lineNumber":219,"sourceCode":"                        buffer.extend(read);\n                    } else {\n                        // Do not continue, as there is too much pending data\n                        // in the buffer. Most likely the client does not\n                        // implement a proper back-pressure management system,\n                        // thus we terminate it.\n                        tracing::error!(\"closing channel thread because of buffer overflow\");\n\n                        panic!(\n                            \"buffer overflow ({}/{} bytes)\",\n                            buffer.len() + read.len(),\n                            MAX_LINE_SIZE\n                        );\n                    }\n                }\n                Err(err) => {\n                    tracing::error!(\"closing channel thread with traceback: {}\", err);\n\n                    panic!(\"closing channel\");\n                }\n            }\n        }\n    }\n\n    fn ensure_start(&self, mut stream: &TcpStream) -> Result<ChannelMode, ChannelHandleError> {\n        #[allow(clippy::never_loop)]\n        loop {\n            let mut read = [0; MAX_LINE_SIZE];\n\n            match stream.read(&mut read) {\n                Ok(n) => {\n                    if n == 0 {\n                        return Err(ChannelHandleError::Closed);\n                    }\n\n                    let mut parts = str::from_utf8(&read[0..n]).unwrap_or(\"\").split_whitespace();\n","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/valeriansaliou/sonic/blob/e6a72da6a532bc3f31d7d93ef1e0964a1a5d01b2/server/src/channel/handle.rs#L201-L237","documentation":"When the channel read loop returns an Err from the stream handling, the server logs the error and panics with 'closing channel', terminating that client's channel thread. It is a catch-all teardown for any I/O/protocol error on the connection.","triggerScenarios":"Any Err propagated from the stream handling inside handle_stream — e.g. TCP read failures, protocol parse errors, connection reset — while a client is attached.","commonSituations":"Client abruptly disconnecting mid-command; network interruption between client and server; malformed commands from a non-conforming client; socket timeouts.","solutions":["Inspect the preceding 'closing channel thread with traceback: {}' log line for the root cause","Fix the client to send well-formed, newline-terminated commands","Ensure the client closes connections cleanly and reconnects with backoff","Check network stability / proxies between client and server"],"exampleFix":"// client\n// before\nstream.write_all(payload.as_bytes()); // missing terminator, may vanish mid-write\n// after\nstream.write_all(format!(\"{}\\n\", payload).as_bytes())?;\nstream.flush()?;","handlingStrategy":"retry","validationCode":"// client: ensure newline-terminated, well-formed commands\nassert!(command.ends_with('\\n') && !command.contains(\"\\r\\n\\r\\n\"));","typeGuard":null,"tryCatchPattern":"// reconnect with backoff on any channel error\nloop {\n    match client.ping() {\n        Ok(_) => break,\n        Err(_) => { sleep(backoff); backoff *= 2; reconnect(); }\n    }\n}","preventionTips":["Always close sockets cleanly; drain pending responses before drop","Send only protocol-valid commands and read replies promptly","Monitor server logs for 'closing channel thread with traceback' root causes"],"tags":["network","panic","tcp","connection"],"backgroundTag":"connection-reset","analyzedSha":"e6a72da6a532bc3f31d7d93ef1e0964a1a5d01b2","analyzedAt":"2026-09-01T14:10:00.384Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T20:17:18.057Z"}