Toby 스프링3 1부 4장 예외
19 Sep 2017 | 스프링 spring 예외초난감 예외처리
- catch로만 잡고 어떠한 조치도 하지 않는다.
- catch블록을 이용해 화면에 에러메시지를 출력한 것은 예외를 처리한 게 아니다
- 무의미하고 무책임한 throws
모든 예외는 적절하게 복구 되든지 아니면 작업을 중단시키고 운영자 또는 개발자에게 분명하게 통보해야 한다.
예외의 종류와 특징
- Error : java.lang.Error: 시스템에서 뭔가 비정상적인 상황이 발생했을 경우에 사용된다. 주로 VM에서 발생 시키므로 catch블록으로 잡아봤자 아무런 대응 방법이 없다.
- Exception
- check Exception : 반드시 예외처리를 해야 한다.
- unCheck Exception
- RuntimeException : 필요 할 때만 예외처리를 한다.
예외처리 방법
- 예외 복구 : 예외가 처리 됐으면 비록 기능적으로 사용자에게 예외상황으로 비쳐도 애플리케이션 에서는 정상적으로 설계된 흐름을 따라 진행돼야 한다.
- 정해진 횟수만큼 재시도 해서 실패했다면 예외 복구는 포기해야 한다.
- 예외처리 코드를 강제하는 체크 예외들 은 이렇게 예외를 어떤 식으로 복구할 가능성이 있는 경우에 사용한다.
- 예외처리 회피 : 예외처리를 자신이 담당하지 않고 자신을 호출한 쪽으로 던져버리는 것
- 콜백과 템플릿처럼 긴밀하게 역할을 분담하고 있는 관계가 아니라면 자신의 코드에서 발생한 예외를 그냥 던져버리는 건 무책임한 책임회피 일수 있다.
- 예외를 회피하는 것은 예외를 복구하는 것처럼 의도가 분명해야 한다.
- 예외 전환 : 예외 회피와 비슷하게 예외를 복구해서 정상적인 상태로는 만들 수 없기 때문에 예외를 메소드 밖으로 던지는 것이다. 하지만 예외 회피와 달리, 발생한 예외를 적절한 예외로 전환해서 던진다.
- 의미를 분명하게 해줄 수 있는 예외로 바꿔주기 위해 사용, 보통 전환하는 예외는 원래 발생한 예외를 담아서 중첩 예외(nested exception)로 만드는 것이 좋다
- 예외를 처리하기 쉽고 단순하게 만들기 위해 포장(wrap)하는 것이다. 중첩 예외를 이용해 새로운 예외를 만들고 원인이 되는 예외를 내부에 담아서 던지는 방식은 같다. 주로 예외처리를 강제하는 체크 예외를 언체크 예외인 런타임 예외로 바꾸는 경우 사용한다.
비즈니스적 예외 처리는 check exception을 사용한다.
복구가 불가능한 예외는 가능한 한 런타임 예외로 포장해서 던지게 해서 다른 계층의 메소드를 작성할 때 불필요한 throw 선언이 들어가지 않도록 해줘야 한다.
예외처리 전략
런타임 예외의 보편화
- JEE 서버 환경에서는 서버의 특정 계층에서 예외가 발생했을 때 작업을 일시 중지하고 사용자와 바로 커뮤니케이션하면서 예외상황을 복구할 수 있는 방법이 없다. 차라리 애플리케이션 차원에서 예외상황을 미리 파악하고, 예외가 발생하지 않도록 차단하는 것이 좋다. 또는 프로그램의 오류나 외부환경으로 인해
애플리케이션 예외
- 예외상황에서는 비즈니스적인 의미를 띤 예외를 던지도록 만드는 것이다. 이때 예외는 의도적으로 체크 예외로 만든다. 자주 발생 가능한 예외상황에 대한 로직을 구현하도록 강제해주는 게 좋다.
예외 전환
JDBC의 한계
- 비표준 SQL
- 호환성 없는 SQLException의 DB 에러 정보
DB 에러코드 매핑을 통한 전환 : 스프링은 DB별 에러 코드를 분류해서 스프링이 정의한 예외 클래스와 매핑해놓은 에러 코드 매핑정보 테이블을 만들어 두고 이를 이용한다.
JDBCTemplate는 SQLException을 단지 런타임 예외인 DataAccessException으로 포장 하는 것이 아니라 DB의 에러 코드를 DataAccessException 계층의 클래스 중 하나로 매핑해 준다.
DAO 인터페이스와 DataAccessException 계층 구조
DataAccessException은 JAVA의 주요 데이터 액세스 기술에서 발생할 수 있는 대부분의 예외를 추상화하고 있다.
정리
- 예외를 잡아서 아무런 조치를 취하지 않거나 의미 없는 throws 선언을 남발하는 것은 위험하다.
- 예외는 복구하거나 예외처리 오브젝트로 의도적으로 전달하거나 적절한 예외로 전환해야 한다.
- 좀 더 의미 있는 예외로 변경하거나, 불필요한 catch/throw를 피하기 위해 런타임 예외로 포장하는 두 가지 방법의 예외 전환이 있다.
- 복구할 수 없는 예외는 가능한 한 빨리 런타임 예외로 전환하는 것이 바람직하다.
- 애플리케이션의 로직을 담기 위한 예외는 체크 예외로 만든다.
- JDBC의 SQLException은 대부분 복구할 수 없는 예외이므로 런타임 예외로 전환될 필요가 있다.
- 스프링은 DataAccessException을 통해 DB에 독립적으로 적용 가능한 추상화된 런타임 예외 계층을 제공한다.
- DAO를 데이터 액세스 기술에서 독립시키려면 인터페이스 도입과 런타임 예외 전환, 기술에 독립적인 추상화된 예외로 전환이 필요하다.
Comments