error-stack 0.6.0

A context-aware error-handling library that supports arbitrary attached user data
Documentation

crates.io libs.rs rust-version documentation license

Open issues / Discussions

error-stack

error-stack is a context-aware error-handling library that supports arbitrary attached user data.

Read our announcement post for the story behind its origins.

The library enables building a Report around an error as it propagates:

use core::{error::Error, fmt};

use error_stack::{Report, ResultExt};

#[derive(Debug)]
struct ParseExperimentError;

impl fmt::Display for ParseExperimentError {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt.write_str("invalid experiment description")
    }
}

impl Error for ParseExperimentError {}

fn parse_experiment(description: &str) -> Result<(u64, u64), Report<ParseExperimentError>> {
    let value = description
        .parse::<u64>()
        .attach_with(|| format!("{description:?} could not be parsed as experiment"))
        .change_context(ParseExperimentError)?;

    Ok((value, 2 * value))
}

#[derive(Debug)]
struct ExperimentError;

impl fmt::Display for ExperimentError {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt.write_str("experiment error: could not run experiment")
    }
}

impl Error for ExperimentError {}

fn start_experiments(
    experiment_ids: &[usize],
    experiment_descriptions: &[&str],
) -> Result<Vec<u64>, Report<ExperimentError>> {
    let experiments = experiment_ids
        .iter()
        .map(|exp_id| {
            let description = experiment_descriptions.get(*exp_id).ok_or_else(|| {
                Report::new(ExperimentError)
                    .attach(format!("experiment {exp_id} has no valid description"))
            })?;

            let experiment = parse_experiment(description)
                .attach(format!("experiment {exp_id} could not be parsed"))
                .change_context(ExperimentError)?;

            Ok(move || experiment.0 * experiment.1)
        })
        .collect::<Result<Vec<_>, Report<ExperimentError>>>()
        .attach("unable to set up experiments")?;

    Ok(experiments.iter().map(|experiment| experiment()).collect())
}

fn main() -> Result<(), Report<ExperimentError>> {
    let experiment_ids = &[0, 2];
    let experiment_descriptions = &["10", "20", "3o"];
    start_experiments(experiment_ids, experiment_descriptions)?;

    Ok(())
}

This will most likely result in an error and print

Usage

Please see the documentation.

For more examples of error-stack in use, please check out the examples folder.

Contributors

error-stack was created and is maintained by HASH. As an open-source project, we gratefully accept external contributions and have published a contributing guide that outlines the process. If you have questions, please create a GitHub discussion.

License

error-stack is available under either of the [Apache License, Version 2.0] or [MIT license] at your option. Please see the LICENSE file for more information.