시스템이 종료되어야 할 수준의 상황과 같이 수습할 수 없는 심각한 문제
이미 복구가 불가능한 상태의 예외 - 메모리 부족, 시스템 오류 등
→ 이는 개발자가 잡을 수 없음 ex. StackOverflowError, OutOfMemoryError
애플리케이션 로직은 Throwable
예외도 잡아서는 안되며, Exception
부터 잡는 게 적합하다.
#체크_예외
특정 부적절한 상황에 던져지는/던질 수 있는 예외
애플리케이션 로직에서 사용할 수 있는 실질적인 최상위 예외
→ 모두 컴파일러가 체크하는 체크 예외 (RuntimeException
제외) ex. NullPointerException, IllegalArgumentException
RuntimeException
#언체크예외, 런타임예외
컴파일러가 체크하지 않는 언체크 예외로, 이를 포함한 하위 예외는 모두 런타임 예외에 해당한다.
*Exception과 Error 모두에 상속관계를 가지는 Throwable
클래스는 getMessage(), printStackTrace()라는 공통 메서드를 가지며, 이를 통해 오류나 예외의 메시지를 담는다.
🌟 이것만은 지키자! [예외 기본 규칙]예외 = 폭탄 돌리기
catch
: 그 하위 예외들까지 모두 잡기throws
: 그 하위 예외들까지 모두 던지기예외에 의해 시스템 오류가 발생해서는 안 되므로, 이를 WAS가 잡아서 개발자가 설정한 서버 오류 페이지를 보여주는 식으로 처리한다. 즉, 이때는 서버가 죽지 않으므로 예외 상황들을 던지는 게 훨씬 안전!
Checked Exception | Unchecked Exception | |
---|---|---|
처리 방법 | 체크 예외는 잡아서 처리하거나, 또는 밖으로 던지도록 선언해야 한다. 그렇지 않으면 컴파일 오류가 발생한다.⇒ 무조건 잡아서 던지거나 처리하기 | 컴파일러가 예외를 처리하지 않는다. *예외를 던지는 throws를 선언하지 않고, 생략할 수 있다. 이 경우 자동으로 예외를 던진다. |
장점 | *가장 좋은 오류는 컴파일 오류! 개발자가 실수로 예외를 누락하지 않도록 컴파일러를 통해 문제를 잡을 수 있다 | 신경쓰고 싶지 않은 언체크 예외 모두 무시 가능! |
단점 | ① 실제로는 개발자가 모든 체크 예외를 반드시 잡거나 던지도록 처리(throws)해야 하기 때문에 너무 번거로워진다. ② 의존관계에 따른 단점 존재 (여러 계층에 걸친 throws) ③ 복구 불가능한 예외 (DB, 외부 네트워크에서 발생한 예외는 따로 처리할 방법이 없다) | 개발자가 실수로 예외를 누락할 수 있다 |
“예외를 처리할 수 없을 때 예외를 밖으로 던지는 부분(throws 예외
)”을 필수로 선언해야 하는가 생략할 수 있는가!
*기본적으로 언체크(런타임) 예외가 더 좋다!
기본적으로 언체크(런타임) 예외를 사용하자
@Transactional
로 선언적 트랜잭션 처리를 할 때, 체크 예외는 롤백 되지 않고, 언체크 예외는 롤백이 된다
체크 예외는 비즈니스 로직상 의도적으로 던지는 예외에만 사용하자
[예시] 결제 시 포인트 부족, 계좌 이체 실패, 로그인 ID/PW 불일치 등
→ 반드시 해당 예외를 잡아서 처리해야 하는 문제일 때만 사용! (개발자가 실수로 놓칠 수도 있는 부분)
예외 상황을 파악하고 문제를 해결해서 정상 상태로 돌려놓는 것
→ 예외로 어떤 작업의 처리가 불가능하다면 다르게 작업을 처리하도록 유도
예외를 복구할 수 없는 경우, 예외 처리를 직접 처리하지 않고, 자신을 호출한 곳으로 던져버리는 것
→ 다른 메서드로 책임 전가
예외를 복구할 수 없는 경우, 적절한 예외로 변환하여 던지는 것
→ 런타임 예외로 포장하는 것이 이에 해당 ☑️
⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️
예외를 전환할 때는 기존 예외를 반드시 포함해야 한다!
실무에서는 항상 로그를 사용하는 것이 좋다. 로그를 통해 잡힌 예외를 확인하고 원인 분석을 통한 개선이 가능하기 떄문이다.
이때, 스택 트레이스를 출력할 수 있는데 e.printStackTrace()
를 사용하거나 log.info(”ex”, e)
와 같이 로그를 찍어주면, 예외가 로그에 출력된다
→ Cause By - Cause By 로 어떤 예외를 원천을 발생했는지 꼬리를 무는 형식으로 원인을 찾을 수 있다.
자바에는 체크 예외가 더 많고, 이들 중 복구할 수 없는 예외가 정말 많다. throws
를 덕지덕지 붙이거나, 아예 Exception
을 던져버리는 선택도 하는데 이는 절대 권장하지 않는 방법이다.
이를 해결할 수 있는 방법은 런타임 예외로 대신 던지도록 하는 것이다.
→ 이들을 문서화하거나 코드에 throws 런타임 예외
로 명시해줌으로써 개발자가 놓치지 않도록 한다.
Inflearn - 김영한 ‘스프링 DB 1편 - 데이터 접근 핵심 원리’ 강의