Dev Language/EffectiveJava

[Effective Java] 예외의 상세 메시지에 실패 관련 정보를 담으라

ydin 2025. 4. 27. 18:54

요약

예외 발생 원인과 관련된 정보를 필요한 것만 자세히 담아서 알려주도록 하자.

  • 스택 추적에 꼭 넣어야 하는 정보
    • 예외가 발생한 파일 이름/줄번호
    • 스택에서 호출한 다른 메서드들의 파일 이름/줄번호

 

스택 추적(Stack Trace)

  • 스택 추적은 예외 객체의 toString 메서드를 호출해 얻는 문자열
  • 보통은 예외의 클래스 이름 뒤에 상세 메시지가 붙는 형태
  • 실패 원인을 분석하기 위해 얻을 수 있는 유일한 정보

→ 예외의 toString 메서드에 실패 원인에 관한 정보를 꼭 필요한 것만 자세하게 예외의 상세 메시지에 담는 것이 중요하다.

스택 추적에 넣어야하는 정보

  • 예외가 발생한 파일 이름/줄번호
  • 스택에서 호출한 다른 메서드들의 파일 이름/줄번호

 

예시 - IndexOutOfBoundsException

IndexOutOfBoundsException의 상세 메시지는 범위의 최솟값/최댓값, 그 범위를 벗어났다는 인덱스 값을 담아야 한다.

예외 발생하는 상황

  • 인덱스 < 최솟값
  • 인덱스 ≥ 최댓값
  • 최솟값 > 최댓값 (내부 불변식이 심각히 깨진 경우)

위 현상들의 원인은 모두 다르므로, 최솟값/최댓값/인덱스 값 정보를 제공하면 원인을 분석하는데 도움이 될 것이다.

 

예외 생성자에서 상세 메시지 미리 생성하기

실패를 적절하게 포착하는 방법으로 예외 생성자에서 상세 메시지를 미리 생성하는 방법도 있다.

  • 예시 코드
    • 이 코드는 상세 메시지를 만들어내는 코드를 예외 클래스 안으로 모아주는 효과도 있어 클래스 사용자가 메시지를 만드는 작업을 중복하지 않아도 되는 효과도 있다
    public class IndexOutOfBoundsException extends RuntimeException {
        private int lowerBound;
        private int upperBound;
        private int index;
    
        /**
         * IndexOutOfBoundsException을 생성한다. 
         * 
         * @param lowerBound 인덱스의 최솟값
         * @param upperBound 인덱스의 최댓값 + 1
         * @param index 인덱스의 실제값
         */
        public IndexOutOfBoundsException(int lowerBound,
                                         int upperBound,
                                         int index
        ) {
            // 실패를 포착하는 상세 메시지를 생성한다.
            super(String.format(
                    "최솟값 : %d, 최댓값 : %d, 인덱스 : %d",
                    lowerBound, upperBound, index));
    
            // 프로그램에서 이용할 수 있도록 실패 정보를 저장해둔다.
            this.lowerBound = lowerBound;
            this.upperBound = upperBound;
            this.index = index;
        }
    }
    
    • 길이가 5인 배열, arr[5]; → 예외 발생
    • 예외 메시지 : “최솟값 : 0, 최댓값 : 4, 인덱스 : 5”
  • 참고
    • 자바 9에서 IndexOutOfBoundsException의 생성자는 정수 인덱스를 받는다
    public IndexOutOfBoundsException(String  s){ }