Repository navigation
anyhow!: keep the error chain when converting Arc<Error> - #465
Open
Sanjays2402 wants to merge 1 commit into
Open
Sanjays2402 wants to merge 1 commit into
Sanjays2402 wants to merge 1 commit into
Conversation
An anyhow::Error behind an Arc does not implement std::error::Error, so anyhow!(arc) fell through to the message-only path and kept only the outermost context, dropping every cause below it. This adds a SharedKind dispatch arm that wraps the Arc transparently and delegates source() to the inner error's chain, so display, alternate display, source() and chain() all see the full chain again. Downcasting to Arc<Error>, by reference and by value, keeps working as before. Fixes dtolnay#405.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #405.
An anyhow::Error held behind an Arc does not implement std::error::Error (it only derefs to a dyn Error), so anyhow!(arc) matched neither the TraitKind nor the BoxedKind arm and fell through to the message-only path. The result kept only the outermost context: printing with {:#} showed just "error2", source() returned None, and chain() had a single entry, even though the wrapped error still carried "error1" underneath.
This adds a SharedKind dispatch arm for Arc that wraps it transparently and delegates source() to the inner error's chain, so {:#} prints "error2: error1", source() returns the "error1" error, and chain() walks the full chain again. Downcasting to Arc, by reference and by value, keeps working exactly as it did through the old message-only path.
There is deliberately no From<Arc> impl here: the compiler rejects it as conflicting with the blanket From impl, since std could one day provide an Error impl for Arc wrappers of anyhow::Error. For the same reason, a borrowed &'static Error (issue #341) cannot be covered by this dispatch: AdhocKind's blanket impl for &T already applies to it with the same receiver, so a dedicated arm would make the macro call ambiguous. That case still goes through the old message-only path.
Tests: added test_anyhow_from_arc_error_keeps_chain and test_anyhow_from_arc_error_downcast_by_value to tests/test_convert.rs. Both failed on the old code (chain of length 1, source None) and pass now. The full suite passes (cargo test), along with cargo fmt --check, cargo check --no-default-features, and cargo clippy --tests.