Skip to content

Commit

Permalink
feat(error): change Display for Error to only print top error (#3312)
Browse files Browse the repository at this point in the history
hyper's `Error` used to print the error source automatically, preferring
to provide a better default for users who do not know about `Report`.
But, to fit better with the wider ecosystem, this changes the format to
only print the hyper `Error` itself, and not its source.

Closes #2844

BREAKING CHANGE: The format no longer prints the error chain. Be sure to
  check if you are logging errors directly.

  The `Error::message()` method is removed, it is no longer needed.

  The `Error::into_cause()` method is removed.
  • Loading branch information
seanmonstar authored Sep 13, 2023
1 parent 0891c9e commit 50f123a
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 20 deletions.
28 changes: 13 additions & 15 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ pub type Result<T> = std::result::Result<T, Error>;
type Cause = Box<dyn StdError + Send + Sync>;

/// Represents errors that can occur handling HTTP streams.
///
/// # Formatting
///
/// The `Display` implementation of this type will only print the details of
/// this level of error, even though it may have been caused by another error
/// and contain that error in its source. To print all the relevant
/// information, including the source chain, using something like
/// `std::error::Report`, or equivalent 3rd party types.
///
/// The contents of the formatted error message of this specific `Error` type
/// is unspecified. **You must not depend on it.** The wording and details may
/// change in any version, with the goal of improving error messages.
pub struct Error {
inner: Box<ErrorImpl>,
}
Expand Down Expand Up @@ -170,11 +182,6 @@ impl Error {
self.find_source::<TimedOut>().is_some()
}

/// Consumes the error, returning its cause.
pub fn into_cause(self) -> Option<Box<dyn StdError + Send + Sync>> {
self.inner.cause
}

pub(super) fn new(kind: Kind) -> Error {
Error {
inner: Box::new(ErrorImpl { kind, cause: None }),
Expand Down Expand Up @@ -324,11 +331,6 @@ impl Error {
}
}

/// The error's standalone message, without the message from the source.
pub fn message(&self) -> impl fmt::Display + '_ {
self.description()
}

fn description(&self) -> &str {
match self.inner.kind {
Kind::Parse(Parse::Method) => "invalid HTTP method parsed",
Expand Down Expand Up @@ -410,11 +412,7 @@ impl fmt::Debug for Error {

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(ref cause) = self.inner.cause {
write!(f, "{}: {}", self.description(), cause)
} else {
f.write_str(self.description())
}
f.write_str(self.description())
}
}

Expand Down
4 changes: 0 additions & 4 deletions tests/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2318,10 +2318,6 @@ mod conn {
let error = client.send_request(req).await.unwrap_err();

assert!(error.is_user());
assert_eq!(
error.to_string(),
"dispatch task is gone: user code panicked"
);
}

async fn drain_til_eof<T: tokio::io::AsyncRead + Unpin>(mut sock: T) -> io::Result<()> {
Expand Down
3 changes: 2 additions & 1 deletion tests/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ fn post_with_chunked_body() {

#[test]
fn post_with_chunked_overflow() {
use std::error::Error as _;
let server = serve();
let mut req = connect(server.addr());
req.write_all(
Expand All @@ -542,7 +543,7 @@ fn post_with_chunked_overflow() {
.unwrap();
req.read(&mut [0; 256]).unwrap();

let err = server.body_err().to_string();
let err = server.body_err().source().unwrap().to_string();
assert!(
err.contains("overflow"),
"error should be overflow: {:?}",
Expand Down

0 comments on commit 50f123a

Please sign in to comment.