TL;DR
Rust のアプリケーションでエラーを伝播させ、説明を付け足すためのクレート。std::error::Error を実装した任意のエラーを包める anyhow::Error 型を提供する。
仕組み
anyhow::Result<T> は Result<T, anyhow::Error> の型エイリアスである。これを返す関数の中では、std::error::Error を実装したどのエラーも ? で伝播できる。
Context トレイトの context() や with_context() を使うと、低レベルなエラーに上位の説明を付け足せる。with_context() はクロージャを受け取るので、エラーが起きたときだけメッセージを組み立てる。anyhow! マクロはフォーマット文字列からその場でエラーを作り、bail! マクロはそのエラーで早期リターンする。
例
公式ドキュメントの例では、エラーに説明を付け足しながら ? で伝播させている。
use anyhow::{Context, Result};
fn main() -> Result<()> {
...
it.detach().context("Failed to detach the important thing")?;
let content = std::fs::read(path)
.with_context(|| format!("Failed to read instrs from {}", path))?;
...
}注意点
anyhow は derive(Error) マクロを持たない。独自のエラー型を定義したいときは、std::error::Error を自分で実装するか、thiserror などのクレートを使う。