스프링/5. 스프링 DB-1

34. 체크예외 활용

sdafdq 2023. 10. 3. 09:32

일단 기본적으로 언체크 예외를 사용을 한다.

체크예외는 비즈니스 로직상 의도적으로 던지는 경우에만 주로 사용한다.

계좌이체 실패, 결제 시 포인트 부족, 로그인 id, pw 불일치 등

조금 뭐랄까 의도적으로 처리할 일이 있는?

이런 경우는 고객에게 알리거나 등.

 

물론 위의 경우도 100% 체크 예외로 만들어야 하는 것은 아님.

 

근데, 예를 들어 계좌 이체처럼 매우 심각한 문제는 이런 개발자가 놓치면 안되는 예외는 체크 예외로 해 두면 컴파일러가 인지할 수 있음.

 

체크 예외는 뭔가 개발자가 의도적으로 인지하고 싶을 때, 처리하고 싶을 때 컴파일러가 잡아주므로

 

 

보통은 런타임예외(언체크예외)를 주로 씀. 저렇게 의도적으로 인지하거나 처리하고 싶을 경우를 제외 하고는.

아, 이거는 에러 나면 ~~ 이렇게 처리하고 싶은데. 하는 경우

 

 

 

 

체크 예외가 명시적이라 훨씬 좋아보이는데, 왜 언체크 예외를 쓰라고 할까?

 

음.. 먼저 테스트 코드를 보여주겠다.

public class CheckedAppTest {
    @Test
    public void checked(){
        Controller controller = new Controller();
        assertThatThrownBy(()-> controller.request())
                .isInstanceOf(Exception.class);
    }
    
    static class Controller{
        Service service = new Service();

        public void request() throws SQLException, ConnectException {
            service.logic();
        }
    }
    
    static class Service{
        Repository repository = new Repository();
        NetworkClient networkClient = new NetworkClient();

        

        public void logic() throws SQLException, ConnectException {
            repository.call();
            networkClient.call();
        }
    }
    
    static class NetworkClient{
        public void call() throws ConnectException {
            throw new ConnectException("연결 실패");
        }
    }
    
    static class Repository{
        public void call() throws SQLException {
            throw new SQLException("ex");
        }
    }
}

Repository에서 예외를 던지고 (SQL 관련해서 예외가 터질 소지가 있다.)

NetworkClient는 우리가 외부 네트워크랑 소통하게 되면, 우리가 클라이언트 입장이 되고 외부가 서버 입장이 되는데,

얘도 연결 과정 중 에러가 터질 소지가 있다.

 

사실 이것뿐만 아니라 많은 부분들이 수많이 오류가 터질 가능성이 있다.

체크예외는 오류가 터질 가능성만 있어도 무조건 명시해줘야 한다.

 

저기 보면,

서비스, 컨트롤러 까지 타고 올라와 모두 예외를 명시해 줘야 한다.

 

사실, 예외 대부분이 복구 불가능한 예외다. 여기서 복구란 것은 try catch로 잡아서 실시간으로 올바르게 처리하도록 만드는 것이다.

DB서버가 다운됐다던지, 쿼리가 잘못되었다던지, 대부분 복구 불가능 하다.

일부 복구 가능한 예외들도 있지만, 이것은 극히 일부이다.

 

그래서, 어차피 터지고, 대부분 복구가 불가능하기에 따로 명시하지 않고,

서블릿 필터, 스프링 인터셉터, 스프링의 ControllAdvice같은 걸로 그냥 공통으로 해결한다.

 

단, 에러가 발생하면 그걸  로그로 남겨서 슬랙, 문자, 메일등의 알림을 통해서 빠르게 개발자가 전달 받고, 해결할 수 있도록 해야 한다.

 

그렇게 예외가 있을 상황이 다분한 상황에서, 일일히 throw를 해주기는 좀 그렇다.

 

 

더 큰 문제는, 의존하게 되기 때문이다.

예를 들어서, SQLException은 JDBC의 Exception이다.

그럼 나중에 예를 들어 저거를 JDBC가 아니라 JPA로 바꾸게 되면 또 JPAException 이런 식으로 일일히 바꿔야 한다.

객체지향 SOLID에 어긋난다.

거기다가, 서비스, 컨트롤러까지 다 수정해줘야 한다.

 

 

 

그럼 다 throws Exception 하면 되는거 아닌가? 라고 생각할 수 있는데,

그러면 다 Exception으로 던져서 정작 체크예외는 무효화 된다.

 

'스프링 > 5. 스프링 DB-1' 카테고리의 다른 글

37. 스프링으로 예외처리, 반복 해결 체크예외  (0) 2023.10.04
35. 언체크 예외 활용.  (0) 2023.10.04
33. 언체크 예외  (0) 2023.10.03
32. 예외 테스트  (0) 2023.10.02
31. 예외 기본 규칙  (0) 2023.10.02