Rustのエラーハンドリング

Result<T, E>

pub enum Result<T, E> {
Ok(T),
Err(E),
}

エラーをStringで返す

use std::fs::File;
use std::io::Read;
use std::path::Path;
fn file_double<P: AsRef<Path>>(file_path: P) -> Result<i32, String> {
let mut file = File::open(file_path).map_err(|e| e.to_string())?;
let mut contents = String::new();
file.read_to_string(&mut contents)
.map_err(|e| e.to_string())?;
let n: i32 = contents.trim().parse::<i32>().map_err(|e| e.to_string())?;
Ok(2 * n)
}
fn main() {
match file_double("foobar") {
Ok(n) => println!("{}", n),
Err(err) => println!("Error: {:?}", err),
}
}
rustc 1.27.0-nightly (79252ff4e 2018–04–29)

独自のエラー型を定義する

use std::error::Error;
use std::convert::From;
use std::fmt;
use diesel::result::Error as DieselError;
use rocket::http::Status;
use rocket::response::{Response, Responder};
use rocket::Request;
#[derive(Debug)]
pub enum ApiError {
NotFound,
InternalServerError,
}
impl fmt::Display for ApiError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ApiError::NotFound => f.write_str("NotFound"),
ApiError::InternalServerError => f.write_str("InternalServerError"),
}
}
}
impl From<DieselError> for ApiError {
fn from(e: DieselError) -> Self {
match e {
DieselError::NotFound => ApiError::NotFound,
_ => ApiError::InternalServerError,
}
}
}
impl Error for ApiError {
fn description(&self) -> &str {
match *self {
ApiError::NotFound => "Record not found",
ApiError::InternalServerError => "Internal server error",
}
}
}
impl<'r> Responder<'r> for ApiError {
fn respond_to(self, _request: &Request) -> Result<Response<'r>, Status> {
match self {
ApiError::NotFound => Err(Status::NotFound),
_ => Err(Status::InternalServerError),
}
}
}
  1. 独自のエラー型を定義
  2. Errorトレイトを実装
  3. Fromトレイトを実装

独自のエラー型を定義

pub enum ApiError {
NotFound,
InternalServerError,
}

Errorトレイトを実装

impl Error for ApiError {
fn description(&self) -> &str {
match *self {
ApiError::NotFound => "Record not found",
ApiError::InternalServerError => "Internal server error",
}
}
}

Fromトレイトを実装

impl From<DieselError> for ApiError {
fn from(e: DieselError) -> Self {
match e {
DieselError::NotFound => ApiError::NotFound,
_ => ApiError::InternalServerError,
}
}
}

参考

--

--

--

Software engineer

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Takanori Ishibashi

Takanori Ishibashi

Software engineer

More from Medium

Rust Day 14: Leetcode — Path Sum

Rust 002 — Variables, Functions, Conditionals, Loops

Fusion Powered Strings!

Rusty Shorts — Iterators