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을 추가하면 됩니다.

'DEVELOPE' 카테고리의 다른 글
| Interface-based Projection에서 ZonedDateTime Converter 사용 (0) | 2023.02.08 | 
|---|
댓글