-
4장) 4.1 예외Java & Spring/토비의 스프링 3.1 2021. 6. 17. 17:11반응형
4장 예외
4.1 사라진 SQLException
스프링의 JdbcTemplate을 적용하면서 throws SQLException 선언이 적용 후에 사라졌다.
초난감 예외처리
- 예외가 발생하면 catch 블록을 써서 잡는 것은 좋지만 아무 것도 하지 않고 넘어가는 것은 위험
- 프로그램 실행 중 어디에서 오류가 있는지 모른채 무시하고 계속 진행하기 때문
- 조치를 취할 방법이 없다면 잡지 말고 throws를 메소드 밖으로 던지고 자신을 호출한 코드에 예외처리 책임을 전가하는 것이 차라리 낫다
- 실행 창에 로그나 메시지로 남기는 경우 다른 수많은 로그나 메시지에 금방 묻힘
- 예외 처리 시, 반드시 지켜야할 핵심 원칙
- 복구되든지 작업을 중단시키고 운영자 or 개발자에게 분명하게 통보돼야함
- 예외가 발생하면 catch 블록을 써서 잡는 것은 좋지만 아무 것도 하지 않고 넘어가는 것은 위험
무의미하고 무책임한 throws
- 모든 예외를 무조건 던져버리는 선언에는 심각한 문제점이 존재
- 의미 있는 정보를 얻을 수 없고, 적절한 처리를 통해 복구될 수 있는 예외 상황을 다룰 기회를 박탈당함
- 예외를 무시하는 방법이나, 무책임한 throws는 절대 지양해야함
- 모든 예외를 무조건 던져버리는 선언에는 심각한 문제점이 존재
예외의 종류와 특징
- 자바의 예외 3가지
- Error, Exception, RuntimeException
- Error
- 시스템에서 비정상적인 상황이 발생한 경우
- 주로 자바 VM에서 발생, Application 코드에서 잡으려고 하면 안됨
- Exception(CheckedException)
- 애플리케이션 코드의 작업 중 예외 상황이 발생한 경우 사용
- Exception에는 Checked와 UnChecked가 존재
- CheckedException은 Exception의 서브 클래스면서 RuntimeException 클래스를 상속받지 않은 예외들
- 예외를 어떤 식으로든 복구할 가능성이 있는 경우 사용
- RuntimeException(UncheckedException)
- RuntimeException을 상속한 클래스들
- 명시적인 예외처리 강제 X
- catch로 잡거나 throws 하지 않아도 됨
- 명시적으로 throws 선언해줘도 되지만, 무의미
- 프로그램의 오류가 있을 때 발생하도록 의도된 것들
- 피할 수 있지만 부주의로 발생할 수 있는 경우를 위한 예외
- 자바의 예외 3가지
예외처리 방법
- 전략
- 예외 복구
- 예외상황을 파악 ~> 문제 해결 ~> 정상 상태로 작동
- 예외로 인해 기본작업 흐름이 불가능하다면 다른 작업 흐름으로 유도
- 예를 들면, DB 서버에 접속할 때, 횟수에 제한을 두고 연결 재시도를 할 수 있음
- 예외처리 회피
- 자신을 호출한 곳으로 throws 하거나 catch and throw(주로 로그 남기고 다시 던짐)
- JdbcTemplate으로 예를 들면, 콜백 오브젝트 메소드에서 SQLException을 템플릿으로 던짐
- SQLException을 처리하는 일이 콜백 오브젝트의 역할이 아니기 때문
- 자신의 역할이 아닌 경우 throws 하지만, 역할 분담을 제대로 하고 있지 않고 무책임한 throws는 무책임한 회피
- 위의 경우처럼 의도가 명확해야함
- 예외 전환
- 예외를 복구해서 정상적으로 만들 수 없기 때문에 예외를 적절한 예외로 처리하여 메소드 밖으로 던짐
- 목적
- 의미를 분명하게 해줄 수 있는 예외로 바꿔주기 위해
- 서비스 계층 오브젝트가 적절한 복구 작업을 시도 가능
- 전환 예외에 원래 발생한 예외를 담어 중첩 예외(Nested Exception)으로 처리
- 새로운 예외를 만들면서 생성자나 initCause() 메소드로 원인을 넣어줌
- 예외를 포장
- 새로운 예외를 만들고 원인이 되는 예외를 내부에 담아서 던지는 방식은 같음
- 의미를 명확하게 하려는 목적이 아니라는 점이 다름
- 주로 Checked Exception을 Runtime Exception으로 전환하는 경우에 사용
- 의미 있는 예외거나 복구 가능한 예외가 아니라면 런타임 예외인 EJBException으로 포장해서 던지는 편이 좋음
- EJBException은 시스템 익셉션으로 인식하고 트랜잭션을 자동으로 롤백
- 애플리케이션 코드에서 로직상의 예외인 경우는 의도적으로 Checked Exception을 던지는 것이 좋음
- 의미를 분명하게 해줄 수 있는 예외로 바꿔주기 위해
- 예외 복구
- 전략
예외처리 전략
- 런타임 예외의 보편화
- Checked Exception가 일반 예외, UnChecked는 시스템 장애나 프로그램 오류에 사용
- JavaEE에서는 서버 특정 계층에서 예외가 발생했을 때, 작업을 일시 중지하고 사용자와 바로 커뮤니케이션하면서 예외상황을 복구할 수 있는 방법이 없음
- 예외상황을 미리 파악하고 예외가 발생하지 않도록 차단하는 것이 좋음
- 대응이 불가능한 체크 예외는 런타임 예외로 전환해서 던지는게 좋음
- add() 메소드의 예외 처리
- ID 중복의 경우 좀 더 의미 있는 예외인 DuplicatedUserIdException으로 전환해주고, 아니라면 SQLException을 그대로 던지는 예시를 구현
- SQLException은 복구 불가능하고 처리할 것이 없음
- 런타임 예외로 포장해서 메소드 밖으로 던져서 처리
- DuplicatedUserIdException을 잡아서 처리할 수 있다면 런타임 예외로 만드는 것이 좋음
- SQLException은 복구 불가능하고 처리할 것이 없음
- RuntimeException으로 처리하는 경우 예외 상황에 대한 충분한 고려가 필요
- ID 중복의 경우 좀 더 의미 있는 예외인 DuplicatedUserIdException으로 전환해주고, 아니라면 SQLException을 그대로 던지는 예시를 구현
- 애플리케이션 예외
- 애플리케이션 자체 로직에서 의도적으로 발생해서 catch로 조치를 취하도록 요구하는 예외
- 예시
- 은행 계좌에서 출금하는 기능의 메소드
- 예외 경우에 따라 각기 다른 종류의 리턴 값을 돌려주고, 메소드를 호출한 쪽에서 리턴 값을 확인
~> 리턴 값을 명확하게 코드화하고 잘 관리하지 않으면 복잡한 상황 발생
~> 조건문이 자주 등장해서 코드가 지저분해지고 흐름 파악이 어려움 - 예외 상황에서 비즈니스적 의미를 띤 예외를 던짐
의도적으로 체크 예외를 만들어서 개발자가 잊지 않고 예외 상황에 대한 로직을 구현하도록 강제
~> 예외 정보를 함께 넣어 적절한 대응을 하도록 관리
- 예외 경우에 따라 각기 다른 종류의 리턴 값을 돌려주고, 메소드를 호출한 쪽에서 리턴 값을 확인
- 은행 계좌에서 출금하는 기능의 메소드
- 런타임 예외의 보편화
SQLException은 어떻게 됐나?
- SQLException은 코드 레벨에서 복구할 수 있는 예외가 아님
- 예외가 발생했다는 사실을 빠르게 전달하는 것이 중요
- 예외처리 전략을 적용해서 기계적인 throws를 지양
- 빠르게 UncheckedException(RuntimeException)으로 전환하는 것이 좋음
- SQLException은 코드 레벨에서 복구할 수 있는 예외가 아님
반응형'Java & Spring > 토비의 스프링 3.1' 카테고리의 다른 글
5장) 5.1 사용자 레벨 관리 기능 추가 (0) 2021.06.26 4장) 4.2 예외 전환 ~ 4.3 정리 (0) 2021.06.21 3장) 3.6 스프링의 JdbcTemplate~ 3.7 정리 (0) 2021.06.17 3장) 3.4 컨텍스트와 DI ~ 3.5 템플릿과 콜백 (0) 2021.06.11 3장) 3.1 다시 보는 초난감 DAO ~ 3.3 JDBC 전략 패턴의 최적화 (0) 2021.06.11