- JDBC 72022년 07월 16일
- starryeye
- 작성자
- 2022.07.16.오전00:11
https://starryeye.tistory.com/52
[Java 정리] 예외
Java의 예외에 대해 알아보자. java의 예외도 객체이다. 따라서 상속 구조를 가지며, 계층이 존재한다. Java 예외 계층 Throwable 최상위 예외이며 Object를 상속 받고있다. 개발자는 Throwable 예외를 catch
starryeye.tistory.com
위 포스팅을 읽고 시작하자..
지금까지의 포스팅에서 repository 구현체 layer 에서 사용할 DB를 연동하고.. 의존성을 가지는 것으로 볼 수 있다.
다음 두가지 문제에 대해 포스팅 하겠다.
1. 복구 불가능한 예외
2. 의존 관계에 대한 문제
복구 불가능한 예외
DB에서 발생하는 대부분의 예외는 처리가 불가능하다.
SQLException을 예로 들면..
DB에 문제가 있어서 발생하는 예외이다.
SQL문법 오류, DB자체 오류, DB 서버에 문제.. 등등
이러한 문제는 애플리케이션 로직 수준에서 복구가 불가능하다.
-> 이러한 예외들은 서블릿 필터, 스프링 인터셉터, 스프링 ControllerAdvice 등을 사용하여 공통으로 해결하는 것이 좋다.
의존 관계에 대한 문제
SQLException은.. 대부분 복구가 불가능한 예외임과 동시에.. 체크 예외이다.
체크 예외 이므로 throws로 던지게된다면..
catch로 처리하지 않는 이상 호출한 메서드 끝까지 간다.
그러면.. service layer, contoller layer에도 throws로 처리하거나..
catch로 처리를 해야한다는 것인데..
예외 자체에 의존성이 생겨버린다.
특히 service layer는 순수 java로 기술적 의존도가 없어야 좋은 코드이나..
예외에 의존성이 생겨버린다.
이는 큰 문제이다.
mysql, oracle 등 다른 DB를 사용하거나,
Jdbc, JPA 등 다른 DB 연동 기술 스택에 따라 다른 예외가 올라오기 때문에
바뀔때 마다 전 layer를 손봐야 하게 되는 것이다.
(OCP, DI를 통해 기껏 잘 짜놓은 코드도.. 예외 때문에 OCP를 위반할 처지이다.)
<참고>
그러면 throws Exception으로 다 던지면 해결되는 것이 아닌가..?
-> 최상위를 던지기 때문에 개발자가 의도하지 않은 모든 예외가 던져지게 되며..
-> 처리해야할 중요한 체크예외도 컴파일 오류도 안나게 되며 체크예외의 의의가 사라지게된다.
-> 좋은 방법이 아니다.
두 문제를 해결해보자
복구 불가능한 예외는 한번에 모아서 처리 하면 좋으나, 보통 service layer를 거친 후 그 너머에서 처리하게된다..
(그 너머 : 필터, 인터셉터, controllerAdvice...)
그리고.. service layer에서 예외에 대한 의존 관계는 없었으면 좋겠다.
-> 복구 불가능한 예외들을 catch 구문으로 개발자가 만든 runtime 예외로 변환하여 던지면 해결된다.
-> 하지만, runtime 예외는 놓치기 쉽기 때문에.. 문서화는 필수이다.
두 문제를 해결 해놓고 보니..
Repository layer의 구현체들(순수 JDBC, JPA 등)을 인터페이스로 묶을 수 있게 되었다.
각각 구현체에서 원인은 같지만.. 다른 예외가 발생될 텐데..
모두 개발자가 지정한 하나의 runtime 예외로 변환하여 발생 시키면 되고..
언체크 예외이므로 인터페이스에서도 throws 키워드가 안붙어도 되므로 인터페이스화가 가능하다.
주의..
위와 같이 개발자가 새로 RuntimeException을 상속받아 RuntimeSQLException 이라는 언체크 예외를 만들었다.
runSQL 메서드에서 SQLException 체크예외가 발생되었고 throws 키워드를 통해 던지고 있다.
runSQL 메서드를 호출하는 call 메서드에서는 체크 예외를 처리 하기 위해
catch로 해당 체크 예외를 잡고있다.
Repository class에서 끝을 보기 위해서..
Repository class의 call 메서드를 호출하는 다른 클래스에서는 해당 체크예외의 의존성을 가지지 않도록 하기 위해서..
개발해놓은 RuntimeSQLException로 만들어(바꿔치기하여) 던지고 있다.
(언체크 예외 이므로.. call 메서드에서는 throws 키워드로 던지는 처리를 생략한 것을 볼 수 있다.)
주의할 것을 이제 부터이다..
(실제 DB에서 SQLException이 터진 것을 상상해보자.)
SQLException에는 무슨 오류로 해당 예외가 터지게 된 것인지.. 정보들이 가득 담겨있다.
(예시에서는 string으로 "ex"가 담겨있음)
그러나.. 위 코드 처럼
RuntimeSQLException예외 생성자에 Throwable cause 파라미터를 받아서
throw new RuntimeSQLException(e) 로 원본 예외의 정보를 전달 해놓지 않으면...
원본 예외의 중요한 정보들이 다 날라가서 이슈 분석에 큰 문제가 생겨버린다.
주의하자..
다음글이전글이전 글이 없습니다.댓글