Closed
Description
Version
f1b89c1
Platform
Any
Description
Today the std::fmt::Display
impl for hyper::Error
has the following snippet:
Lines 500 to 501 in f1b89c1
and the std::error::Error::source
impl for hyper::Error
reads as such:
Lines 510 to 513 in f1b89c1
This is somewhat problematic for code that properly prints out the error causation chain. e.g. I have seen an error like this:
error: error trying to connect: tcp connect error: Connection refused (os error 111)
caused by: tcp connect error: Connection refused (os error 111)
caused by: Connection refused (os error 111)
this is pretty unreadable. Now one might argue that hyper::Error::description()
serves this use-case, and while that's true, it seems pretty awkward to pull in hyper into the code that's implements error presentation layer just to downcast and check for hyper
.
Activity
[-]`hyper::Error` should either print cause in display xor return a `Some` from `Error::cause()`, not both[/-][+]`hyper::Error` should either print `source` in display xor return a `Some` from `Error::cause()`, not both[/+]seanmonstar commentedon Jan 7, 2022
See also #2542
seanmonstar commentedon Jan 7, 2022
I should probably write up some thoughts as to why this is currently the way it is.
Wrapping an error (so that there's an inner source) frequently provides more context that is useful to users. Without showing the source, the extra context can lose some of its meaning. For example, seeing just "error trying to connect" is also too vague, just as "Connection refused" can be. Most users of hyper tend to just log the
Display
output of the error, without anything fancy. So the format for hyper is to default to be most useful to them.I recognize that makes it more verbose for people using utilities to crawl the source chain. I currently chose to cater to the more common case.
I'm also aware that the "error working group" currently recommends against doing what hyper does. But I don't agree, since it means hurting the common case. And since I believe most users will generally just default to logging
{}
of an error, I don't think "more education" will fix that. Thus, I'd suggest that the WG consider instead that errors print their source chain by default, and allow advance users to opt-in to custom formatting. I explored this concept in seanmonstar/errors#1, and have a not-published crate that does this, even...nox commentedon Jan 11, 2022
@seanmonstar What do you think of making
{:#}
not print the source parts?davidpdrsn commentedon Jan 11, 2022
I think
{:#}
would also work for us as well. Then we could make a newtype aroundhyper::Error
that used{:#}
in itsDisplay
impl.I also considered adding a method a la
fn message(&self) -> impl Display
that returnshyper::Error
s message without the source, which we could then use in a newtype. Asked on Discord about that yesterday.The second option feels nicer to me but either should work.
Error::message
#2737feat(error): add `Error::message` (#2737)
davidpdrsn commentedon Feb 11, 2022
To others who might find this. I used the new
hyper::Error::message
to fix this like so:hyper::Error
prints its first cause in its Display impl, causes duplicate printing in many scenarios #27711 remaining item