Spring 예외 포함과 스택 트레이스

강정우·2024년 1월 14일
0

Spring-boot

목록 보기
58/73

예외 포함과 스택 트레이스

예외를 전환할 때는 반드시 기존 예외를 포함해야 한다. 그렇지 않으면 스택 트레이스를 확인할 때 심각한 문제가 발생한다.

@Test
void printEx() {
    Controller controller = new Controller();
    try {
        controller.request();
    } catch (Exception e) {
        //e.printStackTrace();
        log.info("ex", e);
    }
}

로그를 출력할 때 마지막 파라미터에 예외를 넣어주면 로그에 스택 트레이스를 출력할 수 있다.

log.info("message={}", "message", ex)

여기에서 마지막에 ex 를 전달하는 것을 확인할 수 있다. 이렇게 하면 스택 트레이스에 로그를 출력할 수 있다.

예외 포함, 미포함 차이를 위한 테스트 코드

@Slf4j
public class UnCheckedAppTest {
    @Test
    void unchecked() {
        Controller controller = new Controller();
        assertThatThrownBy(controller::request)
                .isInstanceOf(Exception.class);
    }
    @Test
    void printEx() {
        Controller controller = new Controller();
        try {
            controller.request();
        } catch (Exception e) {
            //e.printStackTrace();
            log.info("ex", e);
        }
    }
    static class Controller {
        Service service = new Service();
        public void request() {
            service.logic();
        }
    }
    static class Service {
        Repository repository = new Repository();
        NetworkClient networkClient = new NetworkClient();
        public void logic() {
            repository.call();
            networkClient.call();
        }
    }
    static class NetworkClient {
        public void call() {
            throw new RuntimeConnectException("연결 실패");
        }
    }
    static class Repository {
        public void call() {
            try {
                runSQL();
            } catch (SQLException e) {
                throw new RuntimeSQLException();
            }
        }
        private void runSQL() throws SQLException {
            throw new SQLException("ex");
        }
    }
    static class RuntimeConnectException extends RuntimeException {
        public RuntimeConnectException(String message) {
            super(message);
        }
    }
    static class RuntimeSQLException extends RuntimeException {
        public RuntimeSQLException() {}
        public RuntimeSQLException(Throwable cause) {
            super(cause);
        }
    }
}

기존 예외를 포함하는 경우 (Ok)

public void call() {
    try {
        runSQL();
    } catch (SQLException e) {
        throw new RuntimeSQLException(e); //기존 예외(e) 포함
    }
}

예외를 포함해서 Caused by: 에서 기존에 발생한 java.sql.SQLException 과 스택 트레이스를 확인할 수 있다.

기존 예외를 포함하지 않는 경우 (Non)

public void call() {
    try {
        runSQL();
    } catch (SQLException e) {
        throw new RuntimeSQLException(); //기존 예외(e) 제외
    }
}

예외를 포함하지 않아서 기존에 발생한 java.sql.SQLException 과 스택 트레이스를 확인할 수 없다.
즉, 뭐 때문에 해당 예외가 터진건지 알 수 없다.
변환한 RuntimeSQLException 부터 예외를 확인할 수 있다. 이게 지금 우리가 임의로 만들어서 크게 와닿지 않지만 만약 실제 DB에 연동했다면 DB에서 발생한 예외에 sqlException이나 뭐 때문이 문제인지가 다 들어있는 이를 하나도 확인할 수 없는 심각한 문제가 발생한다.

코드를 보면 얘(super())가 다 넘겨준다.

예외를 전환할 때는 꼭! 기존 예외를 포함하자
그럼 원래 exception인 root cause까지 다 확인할 수 있다.

profile
智(지)! 德(덕)! 體(체)!

0개의 댓글