예외를 전환할 때는 반드시 기존 예외를 포함해야 한다. 그렇지 않으면 스택 트레이스를 확인할 때 심각한 문제가 발생한다.
@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);
}
}
}
public void call() {
try {
runSQL();
} catch (SQLException e) {
throw new RuntimeSQLException(e); //기존 예외(e) 포함
}
}
예외를 포함해서 Caused by:
에서 기존에 발생한 java.sql.SQLException 과 스택 트레이스를 확인할 수 있다.
public void call() {
try {
runSQL();
} catch (SQLException e) {
throw new RuntimeSQLException(); //기존 예외(e) 제외
}
}
예외를 포함하지 않아서 기존에 발생한 java.sql.SQLException 과 스택 트레이스를 확인할 수 없다.
즉, 뭐 때문에 해당 예외가 터진건지 알 수 없다.
변환한 RuntimeSQLException 부터 예외를 확인할 수 있다. 이게 지금 우리가 임의로 만들어서 크게 와닿지 않지만 만약 실제 DB에 연동했다면 DB에서 발생한 예외에 sqlException이나 뭐 때문이 문제인지가 다 들어있는 이를 하나도 확인할 수 없는 심각한 문제가 발생한다.
코드를 보면 얘(super()
)가 다 넘겨준다.
예외를 전환할 때는 꼭! 기존 예외를 포함하자
그럼 원래 exception인 root cause까지 다 확인할 수 있다.