@@ -623,7 +623,7 @@ impl Connection {
623623 let line = value. to_string ( ) + "\n " ;
624624 self . stream
625625 . write_all ( line. as_bytes ( ) )
626- . chain_err ( || format ! ( "failed to send {} " , value ) ) ?;
626+ . chain_err ( || format ! ( "failed to send response ({} bytes) " , line . len ( ) ) ) ?;
627627 }
628628 Ok ( ( ) )
629629 }
@@ -754,11 +754,16 @@ impl Connection {
754754 let sender = self . sender . clone ( ) ;
755755 let child = spawn_thread ( "reader" , || Connection :: reader_thread ( reader, sender) ) ;
756756 if let Err ( e) = self . handle_replies ( receiver) {
757- error ! (
758- "[{}] connection handling failed: {}" ,
759- self . addr,
760- e. display_chain( ) . to_string( )
761- ) ;
757+ if is_disconnect ( & e) {
758+ // client went away mid-exchange (broken pipe / reset) — not actionable
759+ debug ! ( "[{}] connection closed by client: {}" , self . addr, e) ;
760+ } else {
761+ error ! (
762+ "[{}] connection handling failed: {}" ,
763+ self . addr,
764+ e. display_chain( ) . to_string( )
765+ ) ;
766+ }
762767 }
763768 self . stats . clients . dec ( ) ;
764769 self . stats
@@ -775,6 +780,25 @@ impl Connection {
775780 }
776781}
777782
783+ /// True if the error chain is rooted in a client disconnect (broken pipe /
784+ /// connection reset / aborted), which is expected and shouldn't be logged as ERROR.
785+ fn is_disconnect ( err : & Error ) -> bool {
786+ use std:: io:: ErrorKind :: * ;
787+ let mut cause: Option < & ( dyn std:: error:: Error + ' static ) > = Some ( err) ;
788+ while let Some ( e) = cause {
789+ if let Some ( io_err) = e. downcast_ref :: < std:: io:: Error > ( ) {
790+ if matches ! (
791+ io_err. kind( ) ,
792+ BrokenPipe | ConnectionReset | ConnectionAborted | UnexpectedEof
793+ ) {
794+ return true ;
795+ }
796+ }
797+ cause = e. source ( ) ;
798+ }
799+ false
800+ }
801+
778802#[ trace]
779803fn get_history (
780804 query : & Query ,
0 commit comments