🦀

Rust言語 anyhowとthiserror

2023/12/08に公開

anyhowとthiserrorとは

anyhowとthiserrorはRustでエラーハンドリングを簡単行うためのクレートで使われます.
実際のアプリ開発でもよく使っています.

anyhow

anyhowでよく使うのはanyhow::Resultanyhow::Contextanyhow!マクロです.
anyhowはErrorトレイトを実装していて,エラーハンドリングをシンプルにしてくれます.実際のアプリ開発をしている時に精神的に楽ですよね.

thieerror

#[derive(Error)]の使用で簡潔にエラー型を定義することが出来ます.
またエラーメッセージを柔軟にカスタマイズすることもできanyhowとthiserrorの組み合わせの醍醐味とも言えます.

サンプルコード

randクレートを用いて乱数を生成しその値をコンソール上に表示します.
ただしその数字が0または4の時はエラーとして表示するようなコードです.

use rand::Rng;
use thiserror::Error;
use anyhow::anyhow;

// thiserrorを用いたエラーの定義
#[derive(Debug, Error)]
enum ErrorType {
    // ErrorType::Error1が返された時は以下のメッセージを表示させる
    // {0}はenumのフィールドの値
    #[error("this is first poisoned numver {0}")]
    Error1(i32),
    #[error("this is second poisoned numver {0}")]
    Error2(i32)
}

fn main() {
    let number = maybe_fale();

    // コンソールに表示
    match number {
        Ok(i) => println!("{}", i),
        Err(err) => println!("{}", err),
    }

}

// 乱数生成関数
fn maybe_fale() -> anyhow::Result<i32> {
    let mut rng =  rand::thread_rng();
    let number = rng.gen_range(0..5);

    if number == 0 {
        // 0の時はErrorType::Error1を返す
        Err(anyhow!(ErrorType::Error1(number)))?
    } else if number == 4 {
        // 0の時はErrorType::Error2を返す
        Err(anyhow!(ErrorType::Error2(number)))?
    } else {
    Ok(number)
    }
}

出力は以下のようになります

  • 0,4以外のとき
Finished dev [unoptimized + debuginfo] target(s) in 0.04s
    Running `target/debug/app`
2
  • 0の時
Finished dev [unoptimized + debuginfo] target(s) in 0.04s
    Running `target/debug/app`
this is first poisoned numver 0
  • 4の時
Finished dev [unoptimized + debuginfo] target(s) in 0.04s
    Running `target/debug/rust-relearn`
this is second poisoned numver 4

Discussion