Skip to content

Instantly share code, notes, and snippets.

@sudachi0114
Last active August 13, 2023 11:32
Show Gist options
  • Save sudachi0114/ac70d4befbd71625d680f7d2a6ab1712 to your computer and use it in GitHub Desktop.
Save sudachi0114/ac70d4befbd71625d680f7d2a6ab1712 to your computer and use it in GitHub Desktop.
use std::fs::File;
// Err を扱いやすくする anyhow と thiserror
use anyhow::{Context, Result};
use thiserror::Error;
/// `thiserror::Error` を derive して enum のそれぞれの要素に対して `#[error("message")]` とすることで
/// `impl fmt::Display for ApiError` に変わってエラーメッセージの振る舞いを追加することができる
#[derive(Debug, Error)]
enum ApiError {
#[error("InternalServerError: {0}")]
InternalServerError(String),
#[error("BadRequest")]
_BadRequest,
#[error("NotFound")]
_NotFound,
}
/// `anyhow::Result<T>` は正常系の `Ok<T>` の型引数のみを受け取っているが
/// エラーを返す時は `.into()` や `.context` で型を変換して返す必要がある
/// これにより標準ライブラリの機能のみを使った実装と比べて
/// `impl error::Error for ApiError{}` の記述を削減したり、戻り値の型をシンプルに書くことができる
fn fetch_api() -> Result<()> {
// API にリクエストする際にエラーが発生したと仮定
Err(ApiError::InternalServerError("[always_my_error]".to_string()).into())
}
fn maybe_fail() -> Result<()> {
let _r = fetch_api()?; // ApiError
let filename = "hoge.txt";
let _f = File::open(filename).context(format!("failed to open file: {}", filename))?; // std::io::Error
Ok(())
}
fn main() -> Result<()> {
let _l = maybe_fail()?;
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment