JAVA/Effective Java

[아이템 73] 추상화 수준에 맞는 예외를 던지라

꾸준함. 2024. 3. 27. 07:16

로그를 확인하는 도중 일을 수행하는 도중 예상치 못한 예외가 발생하면 상당히 당황스러울 수 있습니다.

이는 메서드가 저수준 예외를 처리하지 않고 상위 레이어로 던질 때 종종 발생하며 다음과 같은 문제가 발생할 수 있습니다..

  • 내부 구현 방식을 상위 layer에 드러내 윗 레벨 API를 오염시킬 수 있으며
  • 다음 릴리즈에서 구현 방식이 변경될 경우 다른 예외가 발생해 기존 클라이언트 프로그램을 깨지게 할 수 있음

 

이번 아이템에서는 위 문제를 방지하기 위한 기법들을 소개합니다.

 

1. 상위 메서드에서 저수준 예외를 번역하자

  • 상위 메서드에서는 저수준 예외를 잡아 자신의 추상화 수준에 맞는 예외로 바꿔 던져야하며 이를 `예외 번역(Exception Translation)`이라고 함
  • ex) 데이터베이스 연결을 시도할 때 SQLException이 발생할 수 있음
    • 해당 예외는 데이터베이스와 관련된 문제를 나타냄
    • 그러나 상위 레이어에서는 이 예외를 더 의미 있는 형태로 전환하여 처리할 수 있음

 

 

2. 저수준 예외의 내용이 필요할 경우 예외 연쇄를 사용하자

  • `예외 연쇄(Exception Handling)`이란 문제의 근본 원인(cause)인 저수준 예외를 고수준 예외에 체이닝하는 방식
  • Throwable의 getCause() 메서드와 같은 별도의 접근자 메서드를 통해 필요하면 언제든 저수준 예외를 꺼내 볼 수 있음
  • 대부분의 표준 예외는 예외 연쇄용 생성자를 갖추고 있으며 그렇지 않은 예외라도 Throwable의 initCause() 메서드를 통해 `원인`을 직접 못박을 수 있음
  • 예외 연쇄는 문제의 원인을 추적하는데 도움을 주며 원인과 고수준 예외의 Stack trace를 적절히 통합해줌

 

 

3. 예외 번역을 남용하지 말자

  • 가능하다면 저수준 메서드가 반드시 성공하도록 하여 아래 계층에서는 예외가 발생하지 않도록 하는 것이 최선
  • 때로는 상위 계층 메서드의 매개변수 값을 아래 계층 메서드로 건네기 전 Validator를 이용하여 미리 검사하는 것을 권장
  • 아래 계층에서의 예외를 피할 수 없다면, 상위 계층에서 해당 예외를 조용히 처리하여 문제를 API 호출자에게 전파하지 않는 차선책도 있음
    • 만약 발생한 예외를 단순히 로깅하고 개발자가 디버깅하는 정도로 처리할 수 있다면, 그 방식을 권장

 

 

정리

  • 아래 계층의 예외를 예방하거나 스스로 처리할 수 없고, 해당 예외를 상위 계층에 그대로 노출하기 곤란하다면 예외 번역을 사용하는 것을 권장
    • 이 때 예외 연쇄를 이용하면 상위 계층에는 맥락에 어울리는 고수준 예외를 던지면서 근본 원인도 함께 알려주어 오류 분석에 용이함
    • 하지만 예외 번역을 남용하지는 말자

 

참고

이펙티브 자바

반응형