2. HandlerExceptionResolver에 대하여

Daybreak312·2024년 6월 19일
0

SpringBoot

목록 보기
1/1

스프링 부트의 다양한 예외 처리 방식을 실현하는 HandlerExceptionResolver에 대한 글이다.


1. 예외 처리

Exception이 발생하면, @ControllerAdvice, @ExceptionHandler 등으로 빈에 등록된 여러 클래스에 의해 처리된다.

이러한 클래스들을 이용해서 DispatcherServlet까지 전해진 예외가 처리 가능한지 확인하고,

가능한 클래스에게 예외 처리를 위임하는, HandlerExceptionResolver에 대해서 이야기를 하려 한다.

2. Status Code와 Exception

일부 Exception들은, API를 사용하는 사용자(클라이언트)에게 Status Code를 500이 아닌 다른 코드를 표시해줘야할 이유가 있다.

예를 들어, Controller에서 유효성 검증 실패로 Exception이 발생한 경우 사용자에게 400 Bad Request를 표시해줘야 한다.

이러한 처리들을 하는 클래스를 찾고, 그것들을 실행하는 역할을 하는 객체가 바로 HandlerExceptionResolver의 구현체들이다.

- resolveException 메소드 의역
HandlerExecutionChain을 실행하는 도중에 발생한 예외의 처리를 시도하며, 적절한 에러 페이지를 담은 ModelAndView 객체를 반환합니다.
예외가 성공적으로 처리되었지만 화면이 표시되면 안된다는 것을 말하기 위해 ModelAndView가 비어있을 수도 있습니다. 이를 위해 상태 코드를 설정하는 등의 방법을 사용할 수 있습니다.

스프링부트의 기본 예외 처리기인, DefaultHandlerExceptionResolver를 보면 자주 발생하는 일부 스프링 예외들에 대해 StatusCode를 자동으로 설정해주는 코드가 존재한다.



위는 그러한 DefaultHandlerExceptionResolver의 일부 코드이다.

만약 doResolveException( = resolveException) 메소드의 파라미터로 HttpRequestMethodNotSupportedException 타입의 Exception이 입력되었다면, 그에 맞는 405 상태 코드를 반환한다.

이러한 것과 같은 기능을 하는 클래스가 HandlerExceptionResolver이다.

3. HandlerExceptionResolver의 종류와 DispatcherServlet에서의 처리 순서

DispatcherServelt에서 사용하는 HandlerExceptionResolver는  세 가지의 구현체가 존재한다.

  1. ExceptionHandlerExceptionResolver

  2. ResponseStatusExceptionResolver

  3. DefaultHandlerExceptionResolver

ExceptionHandlerExceptionResolver

예외들 중, @ControllerAdvice, @ExceptionHandler 등으로 처리할 Exception인지 확인하고, 처리를 위임하는 클래스

ResponseStatusExceptionResolver

예외들 중, @ResponseStatus를 통해 Status Code가 지정되어 있는 Exception인지 확인한 후, 그 내용에 맞게 Response를 수정하는 클래스

실제로 @ResponseStatus의 Docs를 보면 아래와 같이 ResponseStatusExceptionResolver가 @see로 연결되어 있다.

DefaultHandlerExceptionResolver

앞의 두 클래스로도 처리되지 않은 Exception일 경우, 최종적으로 스프링의 Exception 중 하나인지 확인하고 그에 맞는 처리를 하는 클래스

이 클래스들은 DispatcherServelt에서 사용되며,

doService() -> doDispatch() -> processDispatchResult() -> processHandlerException()

위 메소드 체인에 걸쳐 아래 필드까지 도달해 Exception을 처리한다.


위 두 개 사진을 보면 알 수 있듯, 위에서 나열한 세 개의 클래스는 DefaultErrorAttributes를 실행한 후 HandlerExceptionResolverComposite에 감싸져 실행된다.

DefaultErrorAttributes


로직과 크게 관계있지 않은 클래스다. 존재 여부만 알고 넘어가겠다.

HandlerExceptionResolverComposite


위에서 나열한 3개의 HandlerExceptionResolver 구현체를 담고 있는 일종의 프록시 클래스로, 세 개 Resolver들을 Chain처럼 걸친 후, Exception을 처리한다.

각 HandlerExceptionResolver를 마치 FilterChain처럼, 위에서 나열한 순서대로 하나씩 거치며 예외를 처리한다.


글을 읽는 이들에게 도움이 되었길 바라며, 이상으로 글을 마치도록 하겠다.

0개의 댓글