- Object: 예외도 객체이므로, 예외의 최상위 부모도 Object
- Throwable: 최상위 예외
- Error: 메모리 부족이나 시스템 오류같이 애플리케이션에서 복구 불가능한 시스템 예외.
- Throwable을 catch로 잡으려 하면 Error도 잡혀서 Throwable은 잡으려 하면 안됨. Exception부터 잡아야 하는 오류로 생각해야함.
- Exceptions
- 체크 예외: 애플리케이션 로직에서 사용할 수 있는 실질적인 최상위 예외. RuntimeException을 제외하고 Exceptions의 하위 예외는 모두 체크 예외임.
- 체크 예외는 잡아서 처리하거나, 밖으로 던지도록 선언해야함.
- 개발자가 실수로 예외를 누락하지 않도록 컴파일러를 통해 문제를 잡아주는 장점이 있지만, 모든 체크 예외를 처리해주어야 하는 번거로움이 생기고, 크게 신경쓰고 싶지 않은 예외도 처리해주어야 한다.
- 언체크 예외(런타임 예외): 컴파일러가 체크하지 않는 언체크 예외.
- 예외를 던지는 throws를 선언하지 않고 생략할 수 있다.
- 신경쓰고 싶지 않은 언체크 예외를 무시할 수 있고, 예외를 밖으로 던지려고 throws 예외를 선언하지 않아도 되어 쓰고싶지 않은 예외의 의존관계를 참조하지 않아도 된다. 하지만 개발자가 실수로 예외를 누락할 수도 있다는 단점이 있다.
- 체크 예외: 애플리케이션 로직에서 사용할 수 있는 실질적인 최상위 예외. RuntimeException을 제외하고 Exceptions의 하위 예외는 모두 체크 예외임.
예외의 기본 규칙
- 예외는 잡아서 처리하거나 던져야 함
- 예외를 잡거나 던질 때 지정한 예외만이 아니라, 그 예외의 자식들까지 함께 처리됨.
예외를 처리하지 못하고 계속 던지면?
- 자바 main() 쓰레드의 경우에는 예외 로그를 출력하면서 시스템이 종료
- 웹 애플리케이션은 종료되면 안되니까 사용자에게 오류 페이지를 보여주어야 함.
예외를 직접 만들 때
- Exception을 상속 받은 예외는 체크 예외가 된다.
- RuntimeException을 상속 받은 예외는 언체크 예외가 된다.
예외 활용
체크 예외 활용
- 체크 예외는 비즈니스 로직 상 의도적으로 던지는 예외에만 사용하기
- 예시
- 계좌 이체 실패
- 결제시 포인트 부족
- 로그인 실패
- 이 경우를 무조건 체크 예외로 만들어야 하는 것은 아님. 개발자가 놓치면 안되는 심각한 문제는 체크 예외로 만들어서 놓치지 않도록 할 수 있음.
- 하지만, SQLException의 경우에는 SQL 문법 문제나 데이터베이스 서버 문제가 있을 수 있는데 서비스 입장에서 복구 불가능하여 굳이 알고싶지 않고, JDBC가 아니라 JPA 기술로 바꾸게 되면 JPAException으로 바꿔야 하는 의존 관계 문제가 발생한다.
- 실무에서 발생하는 예외는 대부분 시스템 예외라서 복구 불가능한데, 체크 예외를 사용하면 서비스와 컨트롤러가 알아야 하는 불필요한 의존 관계가 발생한다.
- 예시
언체크 예외 활용
public void call() {
try {
runSQL();
} catch (SQLException e) {
throw new RuntimeSQLException(e); //기존 예외 e 포함
}
}
이렇게 SQLException을 RuntimeSQLException으로 전환해서 던지면 서비스나 컨트롤러에서 이 예외에 대해 알지 못해도 된다. 이로써 복구 불가능한 예외를 신경쓰지 않을 수 있고, 의존 관계에 대한 문제도 해결된다. JPA로 바꿔도 서비스 코드를 바꾸지 않아도 된다.
런타임 예외는 놓칠 수 있으므로 문서화를 잘해야 한다. 또는 중요한 런타임 예외의 경우에는 throws로 명시하여 인지할 수 있게 해준다.
예외를 전환할 때는 꼭 기존 예외를 포함해서 어떤 예외가 전환된 것인지 알려야 한다.
void printEx() {
Controller controller = new Controller();
try {
controller.request();
} catch (Exception e) {
//e.printStackTrace();
log.info("ex", e);
}
}
System.out에 스택 트레이스를 출력하려면 e.printStackTrace()를 사용하면 된다. 하지만 실무에서는 항상 로그를 사용한다.
log.info의 마지막 파라미터에 예외를 넣어주면 로그에 스택 트레이스를 출력할 수 있다.
728x90
'Spring' 카테고리의 다른 글
[Spring DB2] 데이터 접근 기술 - 시작 (0) | 2024.03.11 |
---|---|
[Spring DB 1편 듣고 복습, 토이 프로젝트 수정] 6. 스프링과 문제 해결 - 예외 처리, 반복 (2) | 2024.03.09 |
[Spring DB 1편 듣고 복습, 토이 프로젝트 수정] 4. 스프링과 문제 해결 - 트랜잭션 - 2 (0) | 2024.02.29 |
[Spring DB 1편 듣고 복습, 토이 프로젝트 수정] 4. 스프링과 문제 해결 - 트랜잭션 - 1 (0) | 2024.02.29 |
[Spring DB 1편 듣고 복습, 토이 프로젝트 수정] 3. 트랜잭션 이해 (3) | 2024.02.27 |