The source() of Errors

Sometimes you want to inspect the source() of an Error. chainerror implements std::error::Error::source(), so you can get the cause of an error.

use chainerror::*;
use std::error::Error;
use std::io;
use std::result::Result;

fn do_some_io() -> Result<(), Box<Error + Send + Sync>> {
    Err(io::Error::from(io::ErrorKind::NotFound))?;
    Ok(())
}

fn func2() -> Result<(), Box<Error + Send + Sync>> {
    let filename = "foo.txt";
    do_some_io().map_err(mstrerr!("Error reading '{}'", filename))?;
    Ok(())
}

fn func1() -> Result<(), Box<Error + Send + Sync>> {
    if let Err(e) = func2() {
        if let Some(s) = e.source() {
            eprintln!("func2 failed because of '{}'", s);
            Err(e).map_err(mstrerr!("func1 error"))?;
        }
    }
    Ok(())
}

fn main() -> Result<(), Box<Error + Send + Sync>> {
    if let Err(e) = func1() {
        eprintln!("{}", e);
    }
    Ok(())
}
#[allow(dead_code)]
mod chainerror {
{{#includecomment ../src/lib.rs}}
}

Note, that because we changed the output of the error in main() from Debug to Display, we don't see the error backtrace with filename and line number.

To enable the Display backtrace, you have to enable the feature display-cause for chainerror.