fix(getobject): distinguish downstream output closure (#5220)

fix(getobject): preserve internal broken pipe failures

Co-authored-by: heihutu <heihutu@gmail.com>
This commit is contained in:
houseme
2026-07-25 16:22:20 +08:00
committed by GitHub
parent ffd1b94e1f
commit 9ddb30139d
5 changed files with 235 additions and 38 deletions
+16 -5
View File
@@ -1500,11 +1500,7 @@ impl<R> GetObjectStreamingReader<R> {
{
return "read_quorum";
}
if error_msg.contains("connection reset")
|| error_msg.contains("broken pipe")
|| error_msg.contains("downstream")
|| error_msg.contains("remote closed")
{
if error_msg.contains("getobject output closed:") {
return "downstream_closed";
}
}
@@ -10608,6 +10604,21 @@ mod tests {
assert_eq!(err.kind(), std::io::ErrorKind::TimedOut);
}
#[test]
fn get_object_streaming_reader_distinguishes_internal_and_output_broken_pipes() {
let internal = std::io::Error::from(std::io::ErrorKind::BrokenPipe);
assert_eq!(GetObjectStreamingReader::<std::io::Cursor<Vec<u8>>>::classify_read_error(&internal), "io");
let output_closed = std::io::Error::new(
std::io::ErrorKind::BrokenPipe,
std::io::Error::other("GetObject output closed: broken pipe"),
);
assert_eq!(
GetObjectStreamingReader::<std::io::Cursor<Vec<u8>>>::classify_read_error(&output_closed),
"downstream_closed"
);
}
#[tokio::test]
async fn put_object_body_read_timeout_guard_aborts_on_stall() {
// Inner stream never yields and never reports EOF (a proxy that forwarded