RUST 에러처리

Alpha, Orderly·2024년 6월 2일

RUST

목록 보기
7/11

panic! 으로 복구 불가능한 에러 처리

  • 실제 패닉을 일으키기 위해선 패닉을 일으킬만한 동작을 하거나 panic! 매크로를 명시적으로 호출한다.
  • 패닉이 일어나면 실패 메시지 출력 > 되감기 > 스택 청소 > 종료
    • 근원을 추적하기 위해 호출 스택을 보여주게 할수도 있다.

panic! 백트레이스

fn main() {
    let v = vec![1, 2, 3];

    v[99];
}
  • 유효한 인덱스를 넘어서는 벡터 접근
  • RUST_BACKTRACE 환경변수를 0이 아닌 값으로 변경한다.

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

Result 로 복구 가능한 에러 처리하기

use std::fs::File;

fn main() {
    let greeting_file_result = File::open("hello.txt");

    let greeting_file = match greeting_file_result {
        Ok(file) => file,
        Err(error) => panic!("Problem opening the file: {:?}", error),
    };
}
  • 파일은 열수 있거나 열지 못할수 있다.
  • Result 자료형으로 반환해 성공시와 실패시를 나눌수 있다.

서로 다른 에러 매핑하기

use std::fs::File;
use std::io::ErrorKind;

fn main() {
    let greeting_file_result = File::open("hello.txt");

    let greeting_file = match greeting_file_result {
        Ok(file) => file,
        Err(error) => match error.kind() {
            ErrorKind::NotFound => match File::create("hello.txt") {
                Ok(fc) => fc,
                Err(e) => panic!("Problem creating the file: {:?}", e),
            },
            other_error => {
                panic!("Problem opening the file: {:?}", other_error);
            }
        },
    };
}
  • 에러 내용에 대해 한번 더 매칭한다!
unwrap_or_else
fn main() {
    let greeting_file = File::open("hello.txt").unwrap_or_else(|error| {
        if error.kind() == ErrorKind::NotFound {
            File::create("hello.txt").unwrap_or_else(|error| {
                panic!("Problem creating the file: {:?}", error);
            })
        } else {
            panic!("Problem opening the file: {:?}", error);
        }
    });
}

숏컷 : unwrap, expect

unwrap

  • Result 값이 Ok 일시 Ok 내부 값 반환
  • Err 일시 panic! 매크로 호출

expect

  • panic! 에러 메시지로 선택할수 있도록 해준다.

에러 전파하기

  • Err를 그대로 리턴한다.
use std::fs::File;
use std::io::{self, Read};

fn read_username_from_file() -> Result<String, io::Error> {
    let username_file_result = File::open("hello.txt");

    let mut username_file = match username_file_result {
        Ok(file) => file,
        Err(e) => return Err(e),
    };

    let mut username = String::new();

    match username_file.read_to_string(&mut username) {
        Ok(_) => Ok(username),
        Err(e) => Err(e),
    }
}

?

use std::fs::File;
use std::io::{self, Read};

fn read_username_from_file() -> Result<String, io::Error> {
    let mut username_file = File::open("hello.txt")?;
    let mut username = String::new();
    username_file.read_to_string(&mut username)?;
    Ok(username)
}
  • Reuslt 의 값이 Ok일시 Ok안의 값이 얻어짐
  • Err일시 Err의 값이 반환된다.
  • Result, Option, FromResidual 에만 사용 가능하다.
use std::error::Error;
use std::fs::File;

fn main() -> Result<(), Box<dyn Error>> {
    let greeting_file = File::open("hello.txt")?;

    Ok(())
}
profile
만능 컴덕후 겸 번지 팬

0개의 댓글