Anyhow Context Error Chains
Enrich errors with anyhow context layers, converting foreign error types into chains that print root causes and section context.
Code
use anyhow::{anyhow, Context, Result};
use std::fs;
use std::path::Path;
fn load_config(path: &Path) -> Result<String> {
fs::read_to_string(path)
.with_context(|| format!("reading config from {}", path.display()))
}
fn parse_port(raw: &str) -> Result<u16> {
raw.trim()
.parse::<u16>()
.context("port must be 1-65535")
.with_context(|| format!("invalid port field: {raw:?}"))
}
fn bootstrap(path: &Path) -> Result<()> {
let content = load_config(path)?;
let port = content
.lines()
.find(|l| l.starts_with("port="))
.and_then(|l| l.split('=').nth(1))
.ok_or_else(|| anyhow!("config missing required field: port"))?;
let parsed = parse_port(port)?;
println!("bootstrap ok, listening on {parsed}");
Ok(())
}
fn main() {
let path = Path::new("app.conf");
match bootstrap(path) {
Ok(()) => println!("done"),
Err(err) => {
// 链式打印:每层 context 依次列出,根因最后
let mut chain = err.chain();
println!("error: {}", chain.next().unwrap());
for cause in chain {
println!(" caused by: {cause}");
}
println!("backtrace available: {}", err.backtrace().status().is_enabled());
}
}
}Report a problem with this exampleOpens a pre-filled issue on GitHub.