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

커스텀 에러 타입

~12 min · errors, custom, from, enum

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

표준 에러 타입이 멀리 데려가지만, 진짜 프로그램은 자기 걸 정의해. 커스텀 에러 타입은 네 코드가 실패할 수 있는 방식을 정확히 나열하게 해 — 그리고 여느 enum 처럼 거기에 패턴 매칭해.

에러 enum

관용적 모양은 실패 모드마다 variant 하나인 enum 이야: NotFound, Invalid(String), Io(...). 호출자가 variant 에 match 해서 각 실패 종류에 다르게 반응할 수 있어 — 타임아웃엔 재시도, parse 에러엔 보고, 없는 파일엔 포기.

From 으로 ? 연결하기

? 가 저수준 에러를 네 enum 으로 변환하게 하려면 From<ThatError> for YourError 를 구현해. 이제 Result<_, YourError> 를 반환하는 함수는 ThatError 로 실패하는 연산에 ? 를 쓸 수 있고, 변환이 자동으로 일어나. Traits 트랙의 From trait 의 구체적 보상이야.

'진짜' 에러 타입엔 Display 와 std::error::Error 를 구현해. Debug 를 derive 하고 Display (사람용 메시지) 더하기 마커 trait std::error::Error 를 구현하면 네 타입이 예의바른 시민이 돼 — Box<dyn Error> 와 쓸 수 있고, 출력 가능하고, 변환 가능해. 약간의 보일러플레이트인데, 바로 다음 레슨의 크레이트가 없애는 거야.

언제 수고할 가치가 있나

일회성 스크립트는 Result<_, String> 이나 Box<dyn Error> 를 반환하고 넘어가도 돼. 남이 의존하는 라이브러리는 정밀한 에러 enum 을 정의해야 호출자가 match 하고 반응할 수 있어. 프로그램 크기 — 그리고 누가 에러를 소비하는지 — 가 얼마나 구조가 값할지 정해.

Code

Display + Error 가진 커스텀 에러 enum·rust
use std::fmt;

#[derive(Debug)]
enum ConfigError {
    Missing,
    Invalid(String),
}

impl fmt::Display for ConfigError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            ConfigError::Missing => write!(f, "config is missing"),
            ConfigError::Invalid(s) => write!(f, "invalid config: {s}"),
        }
    }
}
impl std::error::Error for ConfigError {}

fn parse_port(s: &str) -> Result<u16, ConfigError> {
    s.trim().parse::<u16>().map_err(|_| ConfigError::Invalid(s.into()))
}

fn main() {
    match parse_port("abc") {
        Ok(p) => println!("port {p}"),
        Err(e) => println!("error: {e}"),
    }
}

External links

Exercise

작은 파일-설정 로더용 variant 셋짜리 에러 enum 을 정의해 (NotFound, Empty, Parse(String)). Displaystd::error::Error 를 구현해. Result<Config, ConfigError> 를 반환하는 함수를 쓰고 호출 지점에서 variant 에 match 해. 어느 variant 를 기본값으로-복구 vs 치명적으로 만들래?
Hint
NotFound 는 기본 설정을 정당화할 수 있고; Parse 는 보통 보고할 만한 사용자 실수를 뜻해. 정밀한 enum 에 match 하면 호출자가 variant 마다 그 판단을 내려 — 커스텀 에러 타입의 핵심 전부야.

Progress

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

댓글 0

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

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