Cronex
spring-boot + vue 405 해결법(2) - 디버깅 본문
이 전 디버깅과 동일하게 진행되다가 dispatcherServlet에서 HandleAdapter의 handler 메소드를 실행하며 몇 개의 클래스를 더 거쳐서 controller를 실행됩니다.
이제 작성한 서비스에서 에러를 던지면 위에서 보이는 catch 블록으로 들어오게 됩니다.
dispatcherServlet 에서는 catch문에서 dispatchException에 서비스에서 던진 에러를 할당하고 processDispatchResult를 실행한다.
processDisptchResult에서는 handler를 찾아서 processHandlerException()을 호출한다.
여기서 핸들러[ mappedHandler.handler ]는 아래서 볼 수 있듯이 패키지를 포함하여 method 이름 인자까지 포함되어있는 것을 볼 수 있다.
processHandlerException에서는 디스패처서블릿이 갖고 있는 handlerExcpetionResolvers를 돌면서 각각의 리졸버의 resolveException을 실행하면서 exMv를 얻는다.
첫 번째로 DefaultErrorAttributes 에서는 request에 attribute에 아래 key 값으로 exception을 저장한다.
두 번째로는 HandlerExceptionResolverComposite의 resolveException을 실행하게 되는데, 이 메소드의 설명을 빌리자면 "구성된 예외 해결 프로그램 목록을 반복하여 예외를 해결합니다." 라고 적혀있다. 여기서도 for문을 돌면서 resolver의 resolveException을 실행한다.
첫 번째로 ExceptionHandlerExcpetionResolver를 따라 들어가서 resolveExcpetion 설명을 보자면 "이 리졸버가 적용되어야 하는지(즉, 제공된 처리기[handler]가 구성된 처리기[handler] 또는 처리기[handler] 클래스와 일치하는지) 확인한 다음 doResolveException 템플릿 메서드에 위임합니다." 라고 적혀있다. if블록으로 들어와 doResolveException을 실행한다.
몇 개의 클래스를 거쳐 ExceptionHandlerExceptionResolver의 doResolveHandlerMethodException메소드에 도달하는데 이 메서드의 설명을 보면 "@ExceptionHandler 메서드를 찾아 호출하여 발생한 예외를 처리합니다." 라고 적혀있다.
doResolveHanlderMethodException 메소드에서는 getExceptionHandlerMethod 메서드를 통해 핸들러 메서드를 찾는데 위에 적혀있는 설명을 보자면 "주어진 예외에 대한 @ExceptionHandler 메소드를 찾으십시오. 기본 구현은 먼저 컨트롤러의 클래스 계층 구조에서 메서드를 검색하고 찾지 못한 경우 일부 @ControllerAdvice Spring 관리 빈이 감지되었다고 가정하고 추가 @ExceptionHandler 메서드를 계속 검색합니다." 라고 적혀있는 것으로 보아 여기서 이 전에 정의한 exceptionHandler를 여기서 찾는 듯 하다.
조금 더 아래를 보면 exceptionHandleradviceCache 에 등록한 exceptionHandler가 있는것을 확인할 수 있다.
for문 내부에 resolver.resolveMethod에 인자로 exception을 넘기는데, 여기서 exception를 해결할 수 있는 method를 찾게 된다.
실질적으로 resolveMethodByThrowable 메서드에서 resolveMethodByExceptionType으로 매칭되는 메서드를 찾아서 반환한다.
다시 for문으로 돌아서 반환받은 method를 ServletInvocableHandlerMethod의 인자로 넘기면서 객체를 생성하고 메서드를 종료한다.
doResolveHandlerMethodException에서 메서드를 반환받고 아래에 보이는 exceptionHandlerMethod.invokeAndHandler() 메서드를 실행하게 된다.
아래 과정을 거쳐 정의한 handlerException 메서드에 도착하게 된다.
이 후 처리는 아래와 같다 ResponseEntity를 반환하게 되면 returnValue를 판단하여 그에 맞는 processor를 실행하여 결과를 반환한다.
returnValueHandler의 종류에는 9가지 있는데 여기서는 HttpEntityMethodProcessor[3]아 채택된다.
write() 메서드 내부의 outputMessage.getBody().flush()를 통해 response를 전달하게 된다.
이렇게 핸들러에 도착하여 처리하게 되는 거였습니다..
기나긴 디버깅 이었습니다.. 이 문제를 해결하기 위해 구글링을 통해 검색하고 하였으나, 제게 맞는 해결법이 아니여서 디버깅을 하여 해결하자는 생각으로 하면서 여기까지 진행했네요..
저와 같은 문제로 해결하지 못한 분이 계시다면 이 글을 읽고 해결이 되었으면 좋겠습니다.
'spring-boot > errors' 카테고리의 다른 글
spring-boot + vue 405 해결법(1) (0) | 2023.04.28 |
---|---|
spring boot + vue project router문제와 404 해결 (0) | 2023.04.25 |
spring boot vue 프로젝트 설정 시 webpack-dev-server 오류 (0) | 2023.04.18 |
spring-boot Intellij에서 실행 시 Execution failed for task ':.main()'. 오류 (0) | 2023.04.18 |