anyhowを使う
anyhow::Error
https://docs.rs/anyhow/1.0.44/anyhow/struct.Error.html
動的エラー型を包み込んだエラー型。
Box<dyn std::error::Error>
との違い
- 静的な型
- もどり道(backtrace)を保証する
- narrow pointer
Display representations
Display 表し方
esprintln!("{}", err)
undering error(anyhow::Errorが包み込んだerror) もしくは、contextを表示する。
例: Failed to read instrs from ./path/to/instrs.json
esprintln!("{:#}", err)
anyhowのcausesのデフォルトフォーマットを出力する
例: Failed to read instrs from ./path/to/instrs.json: No such file or directory (os error 2)
esprintln!("{:?}", err)
キャプチャーしたバックトレースを出力する。
例: Error: Failed to read instrs from ./path/to/instrs.json
Caused by: No such file or directory (os error 2)
anyhow::Result<T>
実態
//anyhow type Result = Result<T, anyhow::Error>
fn main
では返すことができない。
anyhow::Errorを伝搬してくれる。
anyhow::Context
Result<T, anyhow::Error>に変換するcontextメソッドを提供する。
std::core::Result<T, E>からの変換
let file = File::open("memo.txt").context(format!("unable to open memo.txt)")?;
Option<T>からの変換
let first = vec.first()?.context("unable to get first from vec")
anyhow! bail!
anyhow!マクロ
anyhow::Errorをかんたんに生成
例: stringからの生成
fn lookup(key: &str) -> Result<V> { if key.len() != 16 { return Err(anyhow!("key length must be 16 characters, got {:?}", key)); } ...
bail!マクロ
実態
return(anyhow!($args....))
これを使うことでかんたんにanyhow::Result<T>にして返すことができる
if !has_permission(user, resource) { bail!("permission denied for accessing {}", resource); }
thiserrorとの組み合わせ
#[derive(Error, Debug)] enum ScienceError { #[error("resouce limit exceeded")] RecursionLimitExceeded, ... } if depth > MAX_DEPTH { bail!(ScienceError::RecursionLimitExceeded); }