hive-c0re: widen nix stderr predicate to cover error:/evaluation warning:, add tests
This commit is contained in:
parent
25893d0f95
commit
70644cb004
3 changed files with 78 additions and 14 deletions
|
|
@ -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")));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue