하리Hari

9. 에러 처리하기 (예외 처리)

코드가 멈추지 않도록 안전망을 만들어봅시다.

코드를 짜다 보면 가끔 생각지도 못한 오류(Error)가 발생해서 프로그램이 멈춰버리곤 해요. 하리는 이럴 때 사용할 수 있는 안전망을 제공한답니다!

일단 해보자:로 위험한 코드를 감싸고, 오류가 발생했다면 ('이름'):으로 에러를 잡아낼 수 있어요.

일단 해보자:
    "안전망 안으로 들어왔습니다!"를 출력하자
    새로운 [오류]("앗! 문제가 생겼어요!")를 발생시키자
    "이 부분은 실행되지 않아요."를 출력하자
오류가 발생했다면 ('에러'):
    틀"잡았다! 에러 내용: {'에러'의 '메시지'}"를 출력하자

위의 코드처럼 억지로 에러를 새로운 [오류]("...")를 발생시키자로 던지면, 프로그램이 멈추지 않고 바로 ‘오류가 발생했다면’ 구문으로 넘어가요.


특정 에러만 골라서 잡기 (Exception Filtering)

에러의 종류(타입)에 따라서 다르게 대처하고 싶을 때도 있죠? 그럴 때는 [특정오류]가 발생했다면 ('에러'):를 써서 원하는 에러만 쏙쏙 골라낼 수 있답니다! 단, 이 방식은 새로운 [특정오류](...)를 발생시키자처럼 직접 만든 에러 클래스를 던졌을 때만 통해요 — 10 / 0 같은 계산에서 엔진이 저절로 내는 에러는 특정 타입으로 걸러낼 수 없고, 항상 맨 아래 오류가 발생했다면으로만 잡힌답니다.

먼저 [오류]를 물려받는 나만의 에러 클래스 두 개를 만들어볼까요?

[결제오류]를 [오류]를 바탕으로 설계하자:
    처음 만들어질 때 ([문자열]인 '초기메시지') 다음과 같이 하자:
        부모의 <처음 만들어질 때>('초기메시지')를 실행하자

[재고오류]를 [오류]를 바탕으로 설계하자:
    처음 만들어질 때 ([문자열]인 '초기메시지') 다음과 같이 하자:
        부모의 <처음 만들어질 때>('초기메시지')를 실행하자

일단 해보자:
    새로운 [재고오류]("품절되었어요!")를 발생시키자
[결제오류]가 발생했다면 ('에러'):
    "결제를 다시 확인해주세요!"를 출력하자
[재고오류]가 발생했다면 ('에러'):
    틀"재고 문제: {'에러'의 '메시지'}"를 출력하자
오류가 발생했다면 ('에러'):
    (참고) 위에서 잡히지 않은 나머지 에러들을 여기서 전부 처리해요.
    '에러'의 '메시지'를 출력하자

[재고오류]를 던졌으니 [결제오류] 핸들러는 건너뛰고 [재고오류] 핸들러가 딱 맞게 실행돼요!


마무리는 항상 (Finally)

에러가 나든 안 나든 “이건 무조건 꼭 실행해 줘!” 하는 코드가 있다면 마무리는 항상:을 쓰면 됩니다.

일단 해보자:
    "안전하게 실행을 시작합니다."를 출력하자
오류가 발생했다면 ('에러'):
    "에러가 났을 때만 실행돼요."를 출력하자
마무리는 항상:
    "에러 발생 여부와 상관없이 항상 실행돼요!"를 출력하자

이렇게 에러 처리를 잘 해두면, 어떤 돌발 상황에서도 든든하게 버티는 프로그램을 만들 수 있어요!


함수 안에서 낸 오류를 밖에서 잡기

오류는 함수 안에서 던져도, 그 함수를 부른 곳의 일단 해보자가 잡아 줘요. 함수는 “이건 안 돼”라고 알리기만 하고, 어떻게 대처할지는 부르는 쪽이 정해요.

<나누기>를 만들자 ([숫자]인 '가', [숫자]인 '나'):
    만약 ('나' == 0) 라면:
        새로운 [오류]("0으로 나눌 수 없어요")를 발생시키자
    ('가' / '나')를 돌려주자

일단 해보자:
    <나누기>(10, 0)을 출력하자
오류가 발생했다면 ('에러'):
    틀"계산 실패: {'에러'의 '메시지'}"를 출력하자

어떤 오류가 어떤 뜻인지 궁금하다면 부록: 자주 만나는 오류를 살펴보세요.

놀이터
결과
코드를 작성하고 '실행' 버튼을 눌러보세요.