From 50f123afc0e6c289030bf8699dbec826dc47572c Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Wed, 13 Sep 2023 09:10:36 -0400 Subject: [PATCH] feat(error): change `Display for Error` to only print top error (#3312) 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. --- src/error.rs | 28 +++++++++++++--------------- tests/client.rs | 4 ---- tests/server.rs | 3 ++- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/error.rs b/src/error.rs index 5f50f3ccf8..eda4f5158e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -8,6 +8,18 @@ pub type Result = std::result::Result; type Cause = Box; /// 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, } @@ -170,11 +182,6 @@ impl Error { self.find_source::().is_some() } - /// Consumes the error, returning its cause. - pub fn into_cause(self) -> Option> { - self.inner.cause - } - pub(super) fn new(kind: Kind) -> Error { Error { inner: Box::new(ErrorImpl { kind, cause: None }), @@ -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", @@ -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()) } } diff --git a/tests/client.rs b/tests/client.rs index 3d46c3fbfa..1d19f8ea1d 100644 --- a/tests/client.rs +++ b/tests/client.rs @@ -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(mut sock: T) -> io::Result<()> { diff --git a/tests/server.rs b/tests/server.rs index 4a514907db..16a5a9afbe 100644 --- a/tests/server.rs +++ b/tests/server.rs @@ -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( @@ -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: {:?}",