파이썬 예외를 다른 유형으로 다시 발생시키기
파이썬 3.x에서는 except 블록 안에서 새로운 예외를 발생시키면 예외 체이닝(exception chaining)이 자동으로 적용됩니다. 이때 원래 발생했던 예외와 새로 발생시킨 예외가 함께 출력되어, 오류의 근본 원인을 추적하기 쉬워집니다.
기본 예제 코드
try:
1 / 0
except ZeroDivisionError as e:
raise ValueError("Sweet n Sour grapes") from e
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
Traceback (most recent call last):
File "C:/Users/TutorialsPoint1/~.py", line 2, in <module>
1/0
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:/Users/TutorialsPoint1/~.py", line 4, in <module>
raise ValueError("Sweet n Sour grapes") from e
ValueError: Sweet n Sour grapes
예외 체이닝의 동작 원리
출력 결과에 포함된 "The above exception was the direct cause of the following exception" 메시지는 앞선 예외(ZeroDivisionError)가 뒤따르는 예외(ValueError)의 직접적인 원인임을 의미합니다.
raise ... from e: 원래 예외를 새 예외의__cause__속성에 명시적으로 연결합니다. 디버깅 시 원인 관계가 가장 명확하게 표시됩니다.from없이 단순히raise만 사용: 파이썬이 자동으로__context__에 이전 예외를 저장하며, "During handling of the above exception, another exception occurred"라는 메시지와 함께 연결됩니다(암시적 체이닝).
체이닝 정보 숨기기: from None
원래 예외의 추적 정보를 외부에 노출하고 싶지 않다면 from None을 사용해 체이닝을 억제할 수 있습니다.
try:
1 / 0
except ZeroDivisionError:
raise ValueError("Sweet n Sour grapes") from None
이 경우 ValueError만 출력되고, 내부의 ZeroDivisionError 정보는 표시되지 않습니다.
정리
파이썬에서 예외를 새로운 유형으로 다시 발생시키려면 except 블록 안에서 raise 새로운예외(...) from 기존예외 형태로 작성하면 됩니다. 이 방식은 원래 예외의 원인을 보존하면서 더 의미 있는 예외 타입으로 변환할 수 있어, 라이브러리 개발이나 에러 처리 로직을 설계할 때 매우 유용합니다.