use chainerror::prelude::v1::*; use std::error::Error; use std::io; use std::result::Result; fn do_some_io() -> Result<(), Box> { Err(io::Error::from(io::ErrorKind::NotFound))?; Ok(()) } derive_str_context!(Func2Error); fn func2() -> Result<(), Box> { let filename = "foo.txt"; do_some_io().context(Func2Error(format!("Error reading '{}'", filename)))?; Ok(()) } derive_str_context!(Func1Error); fn func1() -> Result<(), Box> { func2().context(Func1Error("func1 error".to_string()))?; Ok(()) } fn main() -> Result<(), Box> { if let Err(e) = func1() { if let Some(f1err) = e.downcast_chain_ref::() { eprintln!("Func1Error: {}", f1err); if let Some(f2err) = f1err.find_cause::>() { eprintln!("Func2Error: {}", f2err); } if let Some(f2err) = f1err.find_chain_cause::() { eprintln!("Debug Func2Error:\n{:?}", f2err); } } std::process::exit(1); } Ok(()) }