Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No way to report redundancy-free error chain #1923

Open
spencerwilson opened this issue Aug 3, 2023 · 0 comments
Open

No way to report redundancy-free error chain #1923

spencerwilson opened this issue Aug 3, 2023 · 0 comments

Comments

@spencerwilson
Copy link

spencerwilson commented Aug 3, 2023

disclaimer: The "No way" in the issue title is how it seems to me, but I'd be delighted to be proven wrong!

Actual behavior

In my CLI app I have error reporting that logs a given error + its chain of sources via the format specifier {}. My reporting prints:

error: error sending request for url (https://api.dpm.sh/sources): error trying to connect: dns error: failed to lookup address information: nodename nor servname provided, or not known
  ...because: error trying to connect: dns error: failed to lookup address information: nodename nor servname provided, or not known
  ...because: dns error: failed to lookup address information: nodename nor servname provided, or not known
  ...because: failed to lookup address information: nodename nor servname provided, or not known

My understanding is that I'm using core::error::Error in the way it's intended. As a result, I was confused why there was such redundancy at the various levels.

Expected behavior

My reporting would ideally print:

error: error sending request for url (https://api.dpm.sh/sources)
  ...because: error trying to connect
  ...because: dns error
  ...because: failed to lookup address information: nodename nor servname provided, or not known

Cause

I've gathered that the cause of the duplication is twofold:

I understand this is for the benefit of people who are simply logging a reqwest::Error via {}. What's less clear to me is how an app can control the reporting of the error chain without introducing redundancy.

Possible solutions

Is there any change that could be made to reqwest::Error such that the reporting scheme described above would produce the desired output? Some ideas:

  • Change the Display impls of both reqwest::Error and hyper::Error to be: {} describes only the root error, {:#} describes the entire chain. This is what anyhow::Error does. There may be merit to three widely-adopted crates behaving consistently with one another.
  • Add an alternate mode of formatting to reqwest::Error, {:#}, which would produce the desired output.
  • Add a method to reqwest::Error which returns something akin to a std::path::Display: an opaque struct with an alternate Display impl that produces the desired output.
  • I noted the workaround that @davidpdrsn described in hyper::Error prints its first cause in its Display impl, causes duplicate printing in many scenarios hyperium/hyper#2771 (comment). Maybe a similar workaround is possible here, where a dependent of reqwest could define a type that wraps a reqwest::Error and whose Display impl downcasts things and does alternate formatting of error types that are known to include their source's Display in their own Display.

Are there other options? And would the maintainers be open to merging a PR that implemented any of the above?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant