thiserror
and anyhow
The thiserror
and anyhow
crates are widely used to simplify error handling.
thiserror
is often used in libraries to create custom error types that implementFrom<T>
.anyhow
is often used by applications to help with error handling in functions, including adding contextual information to your errors.
use anyhow::{bail, Context, Result}; use std::fs; use std::io::Read; use thiserror::Error; #[derive(Clone, Debug, Eq, Error, PartialEq)] #[error("{0}์์ ์ฌ์ฉ์ ์ด๋ฆ์ ์ฐพ์ ์ ์์ต๋๋ค.")] struct EmptyUsernameError(String); fn read_username(path: &str) -> Result<String> { let mut username = String::with_capacity(100); fs::File::open(path) .with_context(|| format!("{path}์(๋ฅผ) ์ด์ง ๋ชปํ์ต๋๋ค."))? .read_to_string(&mut username) .context("์ฝ์ง ๋ชปํ์ต๋๋ค.")?; if username.is_empty() { bail!(EmptyUsernameError(path.to_string())); } Ok(username) } fn main() { //fs::write("config.dat", "").unwrap(); match read_username("config.dat") { Ok(username) => println!("์ฌ์ฉ์ ์ด๋ฆ: {username}"), Err(err) => println!("์ค๋ฅ: {err:?}"), } }
This slide should take about 5 minutes.
thiserror
- The
Error
derive macro is provided bythiserror
, and has lots of useful attributes to help define error types in a compact way. - The
std::error::Error
trait is derived automatically. - The message from
#[error]
is used to derive theDisplay
trait.
anyhow
anyhow::Error
๋Box<dyn Error>
์ ๋ํผ ํ์ ์ด๋ผ ํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ณต๊ฐ API๋ก์ ์ฌ์ฉํ๊ธฐ์ ๋ถ์ ํฉํ๋ค๊ณ ํ ์ ์์ง๋ง ๋ง์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋๋ฆฌ ์ฌ์ฉ๋๊ณ ์์ต๋๋ค.anyhow::Result<V>
๋Result<V, anyhow::Error>
์ ํ์ ์จ๋ฆฌ์ด์ค(alias)์ ๋๋ค.- ํ์ํ๋ค๋ฉด
anyhow::Error
์ ์ ์ฅ๋ ์ง์ง ์๋ฌ ํ์ ์ ๊บผ๋ด์ด ๊ฒ์ฌํ ์๋ ์์ต๋๋ค. anyhow::Result<T>
๊ฐ ์ ๊ณตํ๋ ๊ธฐ๋ฅ๋ค์ด Go ์ธ์ด ๊ฐ๋ฐ์๋ค์๊ฒ๋ ์ต์ํ ๊ฒ์ ๋๋ค. Go์ธ์ด์์ ๋ฐํ ๊ฐ์ผ๋ก ์ฌ์ฉํ๋(T, error)
ํจํด๊ณผ ๋น์ทํ๊ธฐ ๋๋ฌธ์ ๋๋ค.anyhow::Context
is a trait implemented for the standardResult
andOption
types.use anyhow::Context
is necessary to enable.context()
and.with_context()
on those types.