Add context to every error from a function (anyhow)

Using anyhow, I can add context to each error individually. Is there a way to set context for all errors returned from a function?

For instance, in the following case:

use anyhow::{anyhow, Result};

fn add(n: u16) -> Result<u16> {
    if n < 10 {
        Err(anyhow!("Smaller than 10").context("cant add"))
    } else if n < 20 {
        Err(anyhow!("Smaller than 20").context("cant add"))
    } else {
        Ok(n + 1)
    }
}

fn main() {
    let n = add(5);
    println!("n: {}", n.unwrap());
}

is there a way to add context to every error at once without having to manually add it to every error?

There are some solutions in this previous thread:

1 Like

In that particular example, you could also do this:

fn add(n: u16) -> Result<u16> {
    if n < 10 {
        Err(anyhow!("Smaller than 10"))
    } else if n < 20 {
        Err(anyhow!("Smaller than 20"))
    } else {
        Ok(n + 1)
    }.context("cant add")
}
1 Like

That works, though I was hoping for something more elegant (perhaps using another library maybe). Any ideas why this functionality hasn't been added to anyhow to do more elegantly (such as maybe having a macro that tells the function to add context)?

One such library is context-attribute.

Also consider that context() is designed for adding additional information at the call site that is not available within the function where an error is generated. Information available where the error is first generated can be included directly in the error message or type.

Adding the same context to every error within a function doesn't really serve the documented purpose:

more context about what higher level step the application was in the middle of.

Instead, it just tells you what function the error came from, which is a problem that is often better solved by backtraces, which should soon be stabilized.

Here's an example of using context to actually provide higher-level context about the error:

let position = add(self.height).context("Tower isn't high enough")?;
3 Likes

Thanks, that provides a lot more context on the use of context (I'm sorry I couldn't resist :wink: )

1 Like