티스토리 뷰

1. 예외 처리란?

Java에서 예외 처리(Exception Handling)는 프로그램 실행 중 발생하는 오류나 비정상적인 상황을 관리하고, 프로그램이 중단되지 않도록 적절히 대응하는 중요한 매커니즘이다. 예외가 발생하면 프로그램은 이를 처리하거나 적절하게 사용자에게 알리고, 정상적인 흐름을 유지하는 것이 중요하다.

 

2. 기존 예외 처리 구조

처음에는 예외 상황마다 동일한 메시지가 출력되도록 했다. InvalidInputException을 발생시키는 상황이 여러 개 있었지만, 모든 경우에 동일한 예외 메시지 ("잘못된 값을 입력하였습니다.")가 출력되었다.

public class Main {

    public static void main(String[] args) {
        final UI ui;
        try {
            ui = new DiaryUI(new DiaryController());
            ui.runRepeatedly();
        } catch (Throwable t) {

        }
    }

    interface UI {
        void runRepeatedly() throws IOException;

        class UIException extends RuntimeException {
        }

        class InvalidInputException extends UIException {
        }
    }

    static class DiaryUI implements UI {
        private final DiaryController server;
        private String selected;

        public DiaryUI(DiaryController server) throws IOException {
            this.server = server;
            server.boot();
            ConsoleIO.printLine(getStartMessage());
        }

        public void runRepeatedly() throws IOException {

            do {
                if (onMenu()) {
                    ConsoleIO.printLine("");
                    ConsoleIO.printLine(getMenu());
                    selected = ConsoleIO.readLine().trim().toUpperCase();
                }

                try {
                    run();
                } catch (InvalidInputException e) {
                    // OLD: 동일한 예외 메세지 출력
                    ConsoleIO.printLine("잘못된 값을 입력하였습니다");
                }

                if (isFinished()) {
                    ConsoleIO.printLine(getFinishMessage());
                    break;
                }

                selected = null;
            } while (isRunning());
        }
....
}
    final void patch(final String id, final String body) {
        validateType(id);
        validateBody(body);
        diaryService.patchDiary(Long.parseLong(id), body);
    }

    private void validateBody(String body) {
        if (body.length() > 30) {
            //OLD: 동일한 예외 메세지 출력
            throw new InvalidInputException();
        }
    }

    private void validateType(String id) {
        try {
            Long.parseLong(id);
        } catch (NumberFormatException e) {
            //OLD: 동일한 예외 메세지 출력
            throw new InvalidInputException();
        }
    }

위의 코드에서는 예외가 발생했을 때 "잘못된 값을 입력하였습니다" 같은 고정된 메시지만 출력된다.

그러나 나는 잘못된 입력에 대한 예외를 "글자 수는 30을 넘을 수 없습니다.", "숫자만 입력 가능합니다" 등 상황에 맞는 더욱 구체적인 메시지로 출력하고 싶었다.

 

3. 상황별 예외 메세지 설정으로 개선

예외 메세지를 상황에 맞게 전달하려면, 예외 생성자에서 메시지를 전달받아 이를 저장하고, 예외가 발생할 때 메세지를 출력할 수 있도록 해야 한다. 이를 위해 InvalidInputExceptionUIException메시지를 전달하는 생성자를 추가해 주었다.

public class Main {

    public static void main(String[] args) {
        final UI ui;
        try {
            ui = new DiaryUI(new DiaryController());
            ui.runRepeatedly();
        } catch (Throwable t) {
            // 예외 처리
        }
    }

    interface UI {
        void runRepeatedly() throws IOException;

        // 기본 예외 클래스
        class UIException extends RuntimeException {
            public UIException(String message) {
                super(message);  // 부모 클래스에 메시지 전달
            }
        }

        // 잘못된 입력에 대한 예외 클래스
        class InvalidInputException extends UIException {
            public InvalidInputException(String message) {
                super(message);  // 부모 클래스에 메시지 전달
            }
        }
    }
}

이제 InvalidInputException을 발생시킬 때, 상황에 맞는 메세지를 생성자에 전달할 수 있다.

 

4. 예외 발생 시 구체적인 메세지 설정

private void validateBody(String body) {
    if (body.length() > 30) {
        throw new InvalidInputException("일기 글자수는 30글자를 넘을 수 없습니다.");
    }
}

private void validateType(String id) {
    try {
        Long.parseLong(id);
    } catch (NumberFormatException e) {
        throw new InvalidInputException("숫자를 입력해주세요.");
    }
}

구체적인 메세지 설정도 해주었다.

  • validateBody(): 일기의 길이가 30자를 초과하면 "일기 글자수는 30글자를 넘을 수 없습니다."라는 메시지를 전달한다.
  • validateType(): id 값이 숫자가 아닌 경우 "숫자를 입력해주세요."라는 메시지를 전달한다.

5. super()

 

5.1 super()란?

super()는 부모 클래스의 생성자를 호출하여, 부모 클래스에 메세지나 상태를 전달하는 역할을 한다. 

예를 들어, InvalidInputException이 UIException을 상속받고, UIException은 RuntimeException을 상속받을 때, 메시지를 부모 클래스에게 전달하는 데 사용된다.

class UIException extends RuntimeException {
    public UIException(String message) {
        super(message);  // 부모 클래스인 RuntimeException에 메시지 전달
    }
}

class InvalidInputException extends UIException {
    public InvalidInputException(String message) {
        super(message);  // UIException에 메시지를 전달
    }
}

위 코드에서, InvalidInputException은 UIException에게 메시지를 전달하고, UIException은 다시 RuntimeException에게 메시지를 전달합니다. 이때 super(message)를 호출하지 않으면 예외 메시지가 부모 클래스에 전달되지 않아, 예외 객체를 생성할 때 메시지가 사라지게 된다.

 

5.2 e.getMessage()의 동작 원리

e.getMessage()는 발생한 예외 객체에 담긴 메세지를 반환하는 메서드이다. 이 메서드는 최종적으로 Throwable 클래스에서 정의된 메서드로, 예외가 발생할 때 전달된 메세지를 반환한다. 예외 메세지는 super()를 통해 부모 클래스에 전달되며, Throwable 클래스가 이를 저장하고 getMessage()를 통해 반환한다.

 

6. 예외 메세지 전달 과정

  1. InvalidInputException에서 예외 발생 시, 전달된 메시지는 UIException으로 전달된다.
  2. UIException은 다시 RuntimeException으로 메시지를 전달한다.
  3. RuntimeException은 최종적으로 Throwable에게 메시지를 전달하고, Throwable 클래스가 이를 저장한다.
  4. catch 블록에서 e.getMessage()를 호출하면, Throwable에 저장된 예외 메시지를 가져와 출력할 수 있다.
try {
    run();
} catch (InvalidInputException e) {
    ConsoleIO.printLine(e.getMessage());  // 상황에 맞는 메시지 출력
}

 

 

이렇게 예외 메세지를 구체적이고 상황에 맞게 설정하기 위해, 사용자 정의 예외 클래스에 super(message)로 메세지를 부모 클래스에 전달하는 방식을 살펴보았다. 

super()의 사용상속 구조 덕분에, 예외 메시지를 상위 클래스까지 전달하여 효율적이고 일관된 예외 처리를 할 수 있게 되었다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함