# chainerror - chainerror
A tutorial for the chainerror rust crate.

# chainerror

`chainerror` provides an error backtrace without doing a real backtrace, so even after you `strip` your binaries, you still have the error backtrace.

Having nested function returning errors, the output doesn't tell where the error originates from.

    use std::path::PathBuf;

    type BoxedError = Box<dyn std::error::Error + Send + Sync>;
    fn read_config_file(path: PathBuf) -> Result<(), BoxedError> {
        // do stuff, return other errors
        let _buf = std::fs::read_to_string(&path)?;
        // do stuff, return other errors
        Ok(())
    }

    fn process_config_file() -> Result<(), BoxedError> {
        // do stuff, return other errors
        let _buf = read_config_file("foo.txt".into())?;
        // do stuff, return other errors
        Ok(())
    }

    fn main() {
        if let Err(e) = process_config_file() {
            eprintln!("Error:\n{:?}", e);
        }
    }

This gives the output:

    Error:
    Os { code: 2, kind: NotFound, message: "No such file or directory" }

and you have no idea where it comes from.

With `chainerror`, you can supply a context and get a nice error backtrace:

    use chainerror::prelude::v1::*;
    use std::path::PathBuf;

    type BoxedError = Box<dyn std::error::Error + Send + Sync>;
    fn read_config_file(path: PathBuf) -> Result<(), BoxedError> {
        // do stuff, return other errors
        let _buf = std::fs::read_to_string(&path).context(format!("Reading file: {:?}", &path))?;
        // do stuff, return other errors
        Ok(())
    }

    fn process_config_file() -> Result<(), BoxedError> {
        // do stuff, return other errors
        let _buf = read_config_file("foo.txt".into()).context("read the config file")?;
        // do stuff, return other errors
        Ok(())
    }

    fn main() {
        if let Err(e) = process_config_file() {
            eprintln!("Error:\n{:?}", e);
        }
    }

with the output:

    Error:
    examples/simple.rs:14:51: read the config file
    Caused by:
    examples/simple.rs:7:47: Reading file: "foo.txt"
    Caused by:
    Os { code: 2, kind: NotFound, message: "No such file or directory" }

`chainerror` uses `.source()` of `std::error::Error` along with `#[track_caller]` and `Location` to provide a nice debug error backtrace. It encapsulates all types, which have `Display + Debug` and can store the error cause internally.

Along with the `ChainError<T>` struct, `chainerror` comes with some useful helper macros to save a lot of typing.

`chainerror` has no dependencies!

Debug information is worth it!

### Features

`display-cause` : turn on printing a backtrace of the errors in `Display`

## Tutorial

Read the Tutorial

## License

Licensed under either of

- Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)

at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.