エラー処理
mainでエラーを正しく処理する
エラー戦略 (2024)
Rust by Example で推奨されているように、Boxing errors は使い始めるための
簡単な戦略と見なされています。
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
// エラーを Box 化する例
let result: Result<(), Box<dyn Error>> = Ok(());
result
}
どのような種類のエラー処理が必要になる可能性があるかを理解するには、Designing
error types in Rust を読み、ライブラリには thiserror を、保守されている
エラー集約の選択肢として anyhow を検討してください。
use thiserror::Error;
#[derive(Error,Debug)]
pub enum MultiError {
#[error("🦀 got {0}")]
ErrorClass(String),
}
fn main() -> Result<(), MultiError> {
// thiserror を使用する例
Ok(())
}
アプリケーション作成者は anyhow を使って列挙型を構成でき、クレートから Result
型をインポートすることで自動 Box 化の挙動を利用できます
use anyhow::Result;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let my_string = "yellow".to_string();
let _my_int = my_string.parse::<i32>()?;
Ok(())
}
Error Chain (2015-2018)
存在しないファイルを開こうとしたときに発生するエラーを処理します。これは、 handle errors in Rust ために必要となる多くのボイラープレートコードを担ってくれる ライブラリ error-chain を使うことで実現されます。
foreign_links 内の Io(std::io::Error) により、自動的に
std::io::Error から error_chain! で定義された型へ変換でき、
その型は Error トレイトを実装します。
以下のレシピは、Unix ファイル /proc/uptime を開いて内容を解析し、最初の
数値を取得することで、システムがどれだけ長く稼働しているかを示します。
エラーがない限り、稼働時間を返します。
この本の他のレシピでは error-chain のボイラープレートは隠されており、⤢ ボタンで コードを展開すると確認できます。
use error_chain::error_chain;
use std::fs::File;
use std::io::Read;
error_chain!{
foreign_links {
Io(std::io::Error);
ParseInt(::std::num::ParseIntError);
}
}
fn read_uptime() -> Result<u64> {
let mut uptime = String::new();
File::open("/proc/uptime")?.read_to_string(&mut uptime)?;
Ok(uptime
.split('.')
.next()
.ok_or("Cannot parse uptime data")?
.parse()?)
}
fn main() {
match read_uptime() {
Ok(uptime) => println!("uptime: {} seconds", uptime),
Err(err) => eprintln!("error: {}", err),
};
}