Watch
0
0
Fork
You've already forked hyperhive
0

hive-c0re: widen nix stderr predicate to cover error:/evaluation warning:, add tests

This commit is contained in:
damocles 2026-10-08 00:15:38 +02:00 • committed by mara
commit 70644cb004
3 changed files with 78 additions and 14 deletions

View file

@ -209,9 +209,11 @@ async fn read_request_line<R: AsyncBufRead + Unpin>(
})
}
/// Whether `e`'s root cause is the peer closing the connection — `serve`'s
/// own `?`s convert a raw `std::io::Error` straight to `anyhow::Error` with
/// no intervening `.context()`, so a direct downcast reaches it.
/// Whether `e`'s root cause is the peer closing the connection.
/// `downcast_ref` searches the whole error chain (anyhow's own
/// `object_downcast`, not just the outermost type), so this finds a
/// wrapped `std::io::Error` whether or not something added `.context()`
/// on top of it.
fn is_broken_pipe(e: &anyhow::Error) -> bool {
e.downcast_ref::<std::io::Error>().is_some_and(|io_err| {
matches!(
@ -731,4 +733,31 @@ mod tests {
assert_eq!(served, 1, "connection after EMFILE not served");
assert_eq!(err.raw_os_error(), Some(libc::EBADF));
}
/// `is_broken_pipe` must recognise both peer-closed kinds whether the
/// `io::Error` reaches it bare (how `serve`'s own `?`s produce it) or
/// wrapped in `.context()` (anyhow's `downcast_ref` walks the whole
/// chain, so wrapping doesn't hide it — confirmed here rather than
/// assumed), and must not misclassify an unrelated `io::Error` or a
/// non-io `anyhow::Error`.
#[test]
fn is_broken_pipe_matches_peer_closed_kinds_only() {
let broken_pipe = std::io::Error::from(std::io::ErrorKind::BrokenPipe);
let conn_reset = std::io::Error::from(std::io::ErrorKind::ConnectionReset);
let permission_denied = std::io::Error::from(std::io::ErrorKind::PermissionDenied);
assert!(is_broken_pipe(&anyhow::Error::new(broken_pipe)));
assert!(is_broken_pipe(&anyhow::Error::new(conn_reset)));
assert!(!is_broken_pipe(&anyhow::Error::new(permission_denied)));
let contextual = anyhow::Error::new(std::io::Error::from(std::io::ErrorKind::BrokenPipe))
.context("write response");
assert!(
is_broken_pipe(&contextual),
"anyhow's downcast_ref searches the whole chain, so a \
.context()-wrapped io::Error must still be found"
);
assert!(!is_broken_pipe(&anyhow::anyhow!("not an io error at all")));
}
}