dtolnay / dtolnay/anyhow

REQUEST: Add method to iterate entire context chain, not just errors

Open
#434 1 comment 1 reaction 0 assignees View on GitHub
Dominant language
Rust
Stars
6.7k
Forks
224
PR merge metrics
No merged PRs in 30d

Description

Currently, `anyhow::Error::chain` exposes a chain over all `Error` types in the context chain. Additionally, `anyhow::Error::downcast[_ref]` gives access to a single non-Error context in the chain. There is however no way to access all non-Error contexts in the chain.

Imagine if one wants to tag errors with a `Tag` enum type. And then later one wants to extract all the tags places on the context. That's currently impossible:

```rust
use anyhow::{bail, Context};

#[derive(Debug)]
pub enum Tag {
One,
Two,
}

impl std::fmt::Display for Tag {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(self, f)
}
}

fn bails() -> anyhow::Result<()> {
bail!("bad!");
}

fn add_one_tag() -> anyhow::Result<()> {
bails().context(Tag::One)?;
Ok(())
}

fn add_two_tag() -> anyhow::Result<()> {
add_one_tag().context(Tag::Two)?;
Ok(())
}

fn main() {
match add_two_tag() {
Ok(()) => {}, // all good
Err(e) => {
// some error, let's get the tags...
if let Some(tag) = e.downcast_ref::() {
println!("found tag through downcast: {}", tag);
}

for _item in e.chain() {
// can't do this because Tag doesn't implement Error
// if let Some(tag) = item.downcast_ref::() {
// println!("found tag through chain: {}", tag);
// }
}
}
}
}
```

I would like to propose either
- a `anyhow::Error::context_chain(&self) -> ContextChain` that allows iterating through the entire chain as a `dyn Any` chain
- a `anyhow::Error::downcast_chain(&self) -> DowncastChain` that iterates over all the contexts that succesfully downcast to type `T`.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.