エラー処理¶
はじめに¶
本サイトにつきまして、【IT技術の知見】はじめに - 俺の技術ノート をご認識のほど宜しくお願いいたします。
01. エラーハンドリング¶
Option と Result¶
Rust には null も例外もなく、値がない可能性は Option<T> (Some(値) または None) で表す。
失敗する可能性は Result<T, E> (Ok(値) または Err(エラー)) で表す。
// トークンがあれば Some(トークン)、なければ None を返す
fn token_for(&self, origin: &str) -> Option<&str> { /* ... */ }
// 成功すれば Ok(パス)、失敗すれば Err(エラー) を返す
fn default_path() -> Result<PathBuf> { /* ... */ }
? 演算子¶
? 演算子は、Err ならその場でエラーを返して関数を抜け、Ok なら中身を取り出す。
? 演算子を使う関数は、戻り値の型が Result である必要がある。
// ? 演算子を使うため、戻り値の型を Result にする
fn main() -> Result<()> {
// Err ならここで main 関数を抜け、Ok なら中身を path に代入する
let path = credentials::default_path()?;
// ...
// 成功を返す
Ok(())
}
with_context と bail!¶
anyhow パッケージの with_context メソッドは、None や Err をメッセージ付きのエラーに変換する。
bail! マクロは、指定したメッセージのエラーをその場で返す (return Err(anyhow!(...)) の短縮形) 。
// None をメッセージ付きのエラーに変換し、? 演算子で返す
let token = creds.token_for(&origin).with_context(|| {
format!("not logged in to {origin}")
})?;
if is_expired(token, now()) {
// このメッセージのエラーをその場で返す
bail!("the token for {origin} has expired");
}