티스토리 뷰

반응형

메서드가 저수준 예외를 처리하지 않고 바깥으로 전파했을 때

  • 수행하려는 일과 관련 없어 보이는 예외가 발생
  • 내부 구현 방식을 드러내어 윗 레벨 API를 오염
  • 구현 방식을 바꾸면 다른 예외가 발생하여 기존 클라이언트 프로그램을 깨지게함

 

 

예외 번역 (exception translation)

위 문제를 피하기 위해선 상위 계층에서 저수준 예외를 잡아 자신의 추상화 수준에 맞는 예외로 바꿔 던져야함 (예외 번역)

try {
    // 저수준 추상화를 이용
} catch (LowerLevelException e) {
    // 추상화 수준에 맞게 번역
    throw new HigherLevelException("exception");
}
// AbstractSequentialList에서 수행하는 예외번역 예시

public abstract class AbstractSequentialList<E> extends AbstractList<E> {

    /**
     * Returns the element at the specified position in this list.
     *
     * @param index index of the element to return
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException if the index is out of range
     *         (index < 0 || index >= size())
     */
    public E get(int index) {
        try {
            return listIterator(index).next();
        } catch (NoSuchElementException exc) {
            throw new IndexOutOfBoundsException("Index: "+index);
        }
    }
}

예외를 번역할 때, 저수준 예외가 디버깅에 도움이 된다면 예외 연쇄(exception chaining)를 사용하는 게 좋다.

 

 

예외 연쇄 (exception chaining)

예왜 연쇄는 문제의 근본 원인인 저수준 예외를 고수준 예외에 실어보내는 방식

try {
    // 저수준 추상화를 이용
} catch (LowerLevelException e) {
    // 저수준 예외를 고수준 예외에 실어보낸다.
    throw new HigherLevelException(e);
}

상위 클래스의 생성자에 이 원인을 건내주어 최종적으로 Throwable 생성자까지 건내게 된다.

그러면 별도의 접근자 메서드 (Throwable의 getCause 메서드)로 언제든 저수준 예외를 꺼내볼 수 있다.

class HigherLevelException extends Exception {
    HigherLevelException(Throwable cause) {
        super(cause);
    }
}
  • Throwable 의 initCause 메서드로 원인을 직접 못박을 수도 있음
  • 예외 연쇄는 문제의 원인에 접근하여 원인과 고수준 예외의 스택 추적 정보를 잘 통합해준다.
  • 예외를 무턱대고 전파하는 것보다 예외 번역이 우수하지만, 남용하면 안됨 → 가능하면 저수준 메서드가 성공하도록 하여 예외를 발생시키지 않는 것이 최선
  • 아래 계층에서 예외를 피할 수 없다면, 상위 계층에서 조용히 처리하여 API 호출자까지 전파하지 않는 방법이 있다. 이럴 때는 발생한 예외를 적절한 로깅 기능으로 기록해두자.

 

 

결론

아래 계층의 예외를 예방하거나 스스로 처리할 수 없고, 그 예외를 상위계층에 그대로 노출하기 곤란하다면 예외 번역을 사용하라.

이 때 예외 연쇄를 사용하면 상위 계층에는 맥락에 어울리는 고수준 예외를 던지면서 근본 원인도 함께 알려주어 오류 분석에 좋다.

반응형
댓글
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday