Rust - anyhow
This chapter presents usage of anyhow
crate.
Objectives
- Implement a chain of functions where one calls another.
- Return an error from the innermost function.
- Add context to the errors on each subsequent level.
- Handle the error on the top level by displaying all the causes.
- Consider
std::io::Error
as well as user-defined error as a root cause.
Implementation
// config.rs
use anyhow::{Result, Context, bail};
pub fn load_config() -> Result<()> {
let path = "myconfig";
let _text = std::fs::read_to_string(path)
.context(format!("Failed to read config file: {}", path))?;
let key = "foo";
bail!("Unknown key '{}'", key);
}
// setup.rs
use anyhow::{Result, Context};
use crate::config;
pub fn setup_app() -> Result<()> {
Ok(config::load_config().context("Failed to configure")?)
}
// launcher.rs
use anyhow::{Result, Context};
use crate::setup;
pub fn launch_app() -> Result<()> {
Ok(setup::setup_app().context("Failed to setup application")?)
}
// main.rs
use anyhow::Result;
mod config;
mod setup;
mod launcher;
fn main() -> Result<()> {
launcher::launch_app()
}
Testing
$ cargo build
$ ./target/debug/anyhow_demo
Error: Failed to setup application
Caused by:
0: Failed to configure
1: Failed to read config file: myconfig
2: No such file or directory (os error 2)
$ touch myconfig
$ ./target/debug/anyhow_demo
Error: Failed to setup application
Caused by:
0: Failed to configure
1: Unknown key 'foo'