DEVELOPE

NoHandlerFoundException ControllerAdvice에서 제어하기

갑스토리 2023. 8. 10. 11:19

NoHandlerFoundException ControllerAdvice에서 제어하기

 

 

대부분 ControllerAdvice에서 에러를 제어하지만 간혹 dispatcherServlet에서 출력하는 에러들이 있습니다.

이에러는 Interceptor에서 로그인하지 않은 사용자를 체크하기 위해 throw된 Exception에 의해 발생하지만 항상 dispatcherServlet에서 에러를 출력하지는 않습니다.

 

 

@Component
class AuthInterceptor: AsyncHandlerInterceptor {
    override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
        /**
         * - 로그인 체크
         */
        if (account.isNotLogin) {
            throw AuthorizationException()
        }

        return true
    }
}

 

그렇다면 언제 dispatcherServlet와 ControllerAdvice에러가 구분될까요?

 

dispatcherServlet 의 에러는 Handler (endpoint)가 존재하지 않을때 발생하게 됩니다.

 

 

 

기본적으로 DispatcherServlet → preHandler(HandlerInterceprot) → Controller → postHandler(HandlerInterceprot) → DispatcherServlet → afterCompletion → 응답으로 동작하기 때문에 afterCompletion이전에 발생한 예외는 모두 DispatcherServlet으로 반환되어 ControllerAdvice에서 핸들링 할 수 있습니다.

하지만 핸들러가 존재하지 않으면 preHandler에서 예외를 발생시키고 Default Error Page인 /error로 재호출되는 패턴입니다.

 

 

미정의된 Handler 요청 또한 ControllerAdvice에서 제어하고 싶다면 다음과 같이 처리할 수 있습니다.

spring:
  mvc.throw-exception-if-no-handler-found: true
  web.resources.add-mappings: false

+
ControllerAdvice NoHandlerFoundException 정의

 

spring.mvc.throw-exception-if-no-handler-found: true 이 옵션만 설정한 경우 매핑된 핸들러가 없다고 착각할 수 있지만 기본적으로 ResourceHttpRequestHandler가 추가되기 때문에 spring.web.resources.add-mappings: false도 비활성화 해야합니다.

만약 사용할 Resource가 있다면 직접 resourceHandler을 추가하면 됩니다.