inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술

HandlerExceptionResolver 시작

왜 null을 반환하면 계속 진행되고, null 이 아니면 예외를 처리하는지 확인해봤습니다

498

명아주
0

왜 HandlerExceptionResolver에서 ModelAndView를 null로 하면 에러가 그대로 진행되고, 빈 ModelAndView를 생성하면 예외가 처리되는지 코드를 한번 열어봤습니다.

궁금하실 분도 있을 것 같아서 글 남깁니다.

아래는 DispatcherServlet의 processHandlerException 메소드 입니다.

@Nullable
protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,
@Nullable Object handler, Exception ex) throws Exception {

// Success and error responses may use different content types
request.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);

// Check registered HandlerExceptionResolvers...
ModelAndView exMv = null;
if (this.handlerExceptionResolvers != null) {
for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) {
exMv = resolver.resolveException(request, response, handler, ex);
if (exMv != null) {
break;
}
}
}
if (exMv != null) {
if (exMv.isEmpty()) {
request.setAttribute(EXCEPTION_ATTRIBUTE, ex);
return null;
}
// We might still need view name translation for a plain error model...
if (!exMv.hasView()) {
String defaultViewName = getDefaultViewName(request);
if (defaultViewName != null) {
exMv.setViewName(defaultViewName);
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using resolved error view: " + exMv, ex);
}
else if (logger.isDebugEnabled()) {
logger.debug("Using resolved error view: " + exMv);
}
WebUtils.exposeErrorRequestAttributes(request, ex, getServletName());
return exMv;
}

throw ex;
}

이 전체코드에서 우리가 구현한 resolveException 처리하는 부분만 떼보면

// Check registered HandlerExceptionResolvers...
ModelAndView exMv = null;
if (this.handlerExceptionResolvers != null) {
for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) {
exMv = resolver.resolveException(request, response, handler, ex);
if (exMv != null) {
break;
}
}
}

이렇게 됩니다. 코드를 열어보니 정말 간단하게도 exMv를 null로 초기화해놓고 등록된 resolver들을 돌면서 resolveException을 호출하여 결과가 null 이 아니면 break하는 것을 볼 수 있습니다.

이렇게 만들어진 exMv(모델앤뷰)가 null 이면 (모든 HandlerExceptionResolver 를 다 돌고도 null)

아래의 if문 

if (exMv != null) {
if (exMv.isEmpty()) {
request.setAttribute(EXCEPTION_ATTRIBUTE, ex);
return null;
}
// We might still need view name translation for a plain error model...
if (!exMv.hasView()) {
String defaultViewName = getDefaultViewName(request);
if (defaultViewName != null) {
exMv.setViewName(defaultViewName);
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using resolved error view: " + exMv, ex);
}
else if (logger.isDebugEnabled()) {
logger.debug("Using resolved error view: " + exMv);
}
WebUtils.exposeErrorRequestAttributes(request, ex, getServletName());
return exMv;
}

throw ex;

조건에 걸리지 않아 throw ex;로 에러를 던지게 됩니다.

exMv가 null이 아니면 exMv의 여러 상태에서 따라 request에 attribute를 설정하거나, viewName 등록,  로깅 등의 처리를 하는 것을 볼 수 있습니다.

 

이처럼 코드를 열어보니 설명해주신 내용에 대해 더 이해가 잘 되는 것 같아 이렇게 글로 남겨서 공유합니다!

 

resolver exception

답변 1

1

김영한

명아주님 공유 감사합니다^^