Skip to content

Commit f65fac1

Browse files
committed
fix(electrum): stop logging full response payload on client disconnect
Broken-pipe/reset errors during send embedded the entire JSON-RPC reply (e.g. a large get_history result) into the error context, which was then logged at ERROR and split across many Cloud Logging entries. Truncate the send-failure context to a byte count and route client disconnects to debug!.
1 parent 4607b77 commit f65fac1

1 file changed

Lines changed: 30 additions & 6 deletions

File tree

src/electrum/server.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ impl Connection {
553553
let line = value.to_string() + "\n";
554554
self.stream
555555
.write_all(line.as_bytes())
556-
.chain_err(|| format!("failed to send {}", value))?;
556+
.chain_err(|| format!("failed to send response ({} bytes)", line.len()))?;
557557
}
558558
Ok(())
559559
}
@@ -676,11 +676,16 @@ impl Connection {
676676
let sender = self.sender.clone();
677677
let child = spawn_thread("reader", || Connection::reader_thread(reader, sender));
678678
if let Err(e) = self.handle_replies(receiver) {
679-
error!(
680-
"[{}] connection handling failed: {}",
681-
self.addr,
682-
e.display_chain().to_string()
683-
);
679+
if is_disconnect(&e) {
680+
// client went away mid-exchange (broken pipe / reset) — not actionable
681+
debug!("[{}] connection closed by client: {}", self.addr, e);
682+
} else {
683+
error!(
684+
"[{}] connection handling failed: {}",
685+
self.addr,
686+
e.display_chain().to_string()
687+
);
688+
}
684689
}
685690
self.stats.clients.dec();
686691
self.stats
@@ -697,6 +702,25 @@ impl Connection {
697702
}
698703
}
699704

705+
/// True if the error chain is rooted in a client disconnect (broken pipe /
706+
/// connection reset / aborted), which is expected and shouldn't be logged as ERROR.
707+
fn is_disconnect(err: &Error) -> bool {
708+
use std::io::ErrorKind::*;
709+
let mut cause: Option<&(dyn std::error::Error + 'static)> = Some(err);
710+
while let Some(e) = cause {
711+
if let Some(io_err) = e.downcast_ref::<std::io::Error>() {
712+
if matches!(
713+
io_err.kind(),
714+
BrokenPipe | ConnectionReset | ConnectionAborted | UnexpectedEof
715+
) {
716+
return true;
717+
}
718+
}
719+
cause = e.source();
720+
}
721+
false
722+
}
723+
700724
#[trace]
701725
fn get_history(
702726
query: &Query,

0 commit comments

Comments
 (0)