use chainerror::{Context as _, ErrorDown}; use std::error::Error; use std::io; fn do_some_io() -> Result<(), Box> { Err(io::Error::from(io::ErrorKind::NotFound))?; Ok(()) } chainerror::str_context!(Func2Error); fn func2() -> Result<(), Box> { let filename = "foo.txt"; do_some_io().context(Func2Error(format!("Error reading '{}'", filename)))?; Ok(()) } chainerror::str_context!(Func1ErrorFunc2); chainerror::str_context!(Func1ErrorIO); fn func1() -> Result<(), Box> { func2().context(Func1ErrorFunc2("func1 error calling func2".to_string()))?; let filename = "bar.txt"; do_some_io().context(Func1ErrorIO(format!("Error reading '{}'", filename)))?; Ok(()) } fn main() -> Result<(), Box> { if let Err(e) = func1() { if let Some(s) = e.downcast_ref::>() { eprintln!("Func1ErrorIO:\n{:?}", s); } if let Some(s) = e.downcast_chain_ref::() { eprintln!("Func1ErrorFunc2:\n{:?}", s); } std::process::exit(1); } Ok(()) }