-
Notifications
You must be signed in to change notification settings - Fork 112
correctly expose HttpError through RetryError::source #580
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes an issue where HttpError was not directly accessible in the error source chain due to the use of #[error(transparent)] in the RequestError::Http variant. The change ensures that users can retrieve HttpError via reflection by using #[error("{0}")] instead, which makes HttpError appear directly in the source chain rather than being skipped in favor of its underlying error.
Key Changes:
- Modified
RequestError::Httpenum variant to use#[error("{0}")]instead of#[error(transparent)]to properly exposeHttpErrorin the error source chain - Added test to verify that
HttpErrorcan be found and accessed through the source chain - Updated test imports to include
HttpErrorandHttpErrorKind
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <[email protected]>
alamb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice find @carlsverre 🙏
| // We need to use `{0}` here rather than `error(transparent)` to ensure that | ||
| // `Error::source` returns `HttpError` rather than the underlying | ||
| // `reqwest::Error` which would happen with `error(transparent)`. | ||
| #[error("{0}")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found this change confusing given the docs on https://docs.rs/thiserror/latest/thiserror/#derives
Errors may use error(transparent) to forward the source and Display methods straight through to an underlying error without adding an additional message. This would be appropriate for enums that need an “anything else” variant.
Specifically the documentation mostly discusses the display implications.
However, I verified that the newly added test fails without this change:
thread 'client::retry::tests::test_retry' (1398936) panicked at src/client/retry.rs:745:9:
HttpError not found in source chain
So in summary nice 🕵️ work @carlsverre (👋 btw -- it is great to see you on github)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, perhaps the thiserror docs could be a bit better. I think it's somewhat of a footgun that source is also transparently forwarded, which effectively means the embedded #[from] Foo is no longer accessible via recursively searching source.
Nice to see you too!
Which issue does this PR close?
Closes #579
Rationale for this change
Consistently expose HttpError in the source chain for all http errors.
What changes are included in this PR?
The issue is caused by
#[error(transparent)], which forwards the source method to the underlying error's source impl. The intention is thattransparentresults in the underlying error appearing to be embedded transparently within the embedding error. This means a user can't retrieve theHttpErrorvia reflection.I also added a test to verify that you can retrieve the HttpError in the source chain.
Are there any user-facing changes?
sourcewill start returning HttpError beforereqwest::Errorwhen executed recursively. Hopefully, users recursively search for errors. This will break users who expectreqwest::Errorto be at a fixed number of steps below the root error type.