C.W.K.
Stream
Lesson 05 of 05 · published

thiserror & anyhow

~11 min · errors, thiserror, anyhow, ecosystem

Level 0Rust 호기심러
0 XP0/80 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete

모든 에러 variant 에 Display, Error, From 을 손으로 쓰는 건 진짜 보일러플레이트야. 두 크레이트가 이 공간을 차지하고, 뭘 고르느냐가 네가 뭘 짓는지 말해줘.

thiserror — 라이브러리용

thiserror구체적 에러 enum 의 보일러플레이트를 생성해. variant 를 쓰고 #[error("...")] 로 표기하면; 매크로가 Display, Error, 그리고 (#[from] 으로) From 변환을 derive 해. 결과는 정밀하고 match 가능한 에러 타입 — 호출자가 특정 실패에 반응하게 라이브러리가 노출해야 할 바로 그거.

anyhow — 애플리케이션용

anyhow 는 아무 에러나 변환되는 catch-all 타입 anyhow::Error 하나를 줘. 에러 타입 이름 짓기를 멈추고 그냥 모든 걸 ? 하면서, .context("설정 로딩 중") 으로 context 를 더해. 애플리케이션 코드 — CLI, 바이너리 — 에 딱이야, 호출자가 에러 종류에 match 할 필요 없고 좋은 메시지랑 backtrace 만 원할 때.

라이브러리는 구체 에러를 노출 (thiserror); 애플리케이션은 타입 하나로 소비 (anyhow). 경험칙: 다른 코드가 네 에러에 `match` 할 거면 thiserror 로 진짜 enum 을 줘. 스택 맨 위에 있고 실패가 context 와 전파되기만 하면 되면 anyhow 를 써. 많은 프로젝트가 둘 다 써 — 라이브러리 크레이트엔 thiserror, 바이너리엔 anyhow.

이건 네가 번 거야

이 크레이트가 뭔지 봐: 매크로 생성 trait 구현이야. thiserror 는 너 대신 From 이랑 Display 를 derive 하고; anyhow 는 네가 이미 이해하는 Box<dyn Error>? 변환에 기대. 마법이 아니야 — 이 트랙의 패턴을 자동화한 거야. 그게 Rust 생태계의 축소판이야: 이미 아는 언어 기능 주변의 보일러플레이트를 없애는 작은 크레이트.

Code

thiserror 가 보일러플레이트를 derive 한다·rust
// Cargo.toml:  thiserror = "2"  (라이브러리)   anyhow = "1"  (앱)
use thiserror::Error;

#[derive(Error, Debug)]
enum DataError {
    #[error("not found")]
    NotFound,
    #[error("bad input: {0}")]
    BadInput(String),
    #[error("io failure")]
    Io(#[from] std::io::Error), // #[from] 이 From + ? 지원을 자동 생성
}

fn load() -> Result<String, DataError> {
    Err(DataError::BadInput("empty".into()))
}

fn main() {
    if let Err(e) = load() {
        println!("{e}"); // #[error(...)] Display 문자열을 씀
    }
}

External links

Exercise

지난 레슨의 커스텀 ConfigError enum 을 thiserror 로 다시 써봐: Error 를 derive 하고, 각 variant 를 #[error("...")] 로 표기하고, std::io::Error#[from] 으로 감싸는 variant 를 더해. 이제 ? 가 io 에러를 네 타입으로 자동 변환하는지 확인해. 매크로가 몇 줄을 아꼈어?
Hint
#[error(...)] attribute 가 손으로 쓴 Display 를 대체하고, #[from] 이 손으로 쓴 From impl 을 대체해. 보통 에러 타입마다 15-20 줄 보일러플레이트를 지워 — 그게 thiserror 가 라이브러리 크레이트에서 거의 보편적인 이유야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 똘이warm

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.