[SpringBoot] 스프링의 에러처리 탐구

2024. 1. 17. 23:14·Spring/SpringBoot

스프링은 어플리케이션에서 발생가능한 에러들에 대해 다양한 처리방법을 제공합니다. 

어플리케이션 내부에서 발생되는 에러를 감지하고 각각에 대한 적절한 처리를 하기 위해, 서블릿의 에러 처리 플로우에 대해 알아볼 필요가 있습니다. 이번 포스팅에서 이에 대해 중점적으로 다뤄 보겠습니다.


 

Spring MVC에서 모든 요청은 디스패쳐 서블릿을 통합니다. 디스패쳐 서블릿은 요청에 따라 HandlerMapping 객체를 통해 적절한 컨트롤러를 실행합니다. 이 과정은 디스패쳐 서블릿의 doDispatch() 함수 내에서 실행됩니다. 함수내에 try-catch문 을 통해 감지된 에러는 적절한 HandlerExceptionResolver를 선택해 에러를 처리하게 됩니다. 따라서, 아래와 같은 워크 플로우를 가집니다. 

 
1. DispatcherServlet - 디스패쳐 서블릿은 스프링 컨테이너에 등록된 핸들러 ( @Controller )중 하나를 선택하여 이를 처리합니다. 
2. DispatcherServlet - 컨트롤러가 위임받은 요청을 처리할때 Exception이 발생하면, 이를 디스패쳐가 감지합니다
(자세히는, DispatcherServlet - processDispatchResult()는 모든 요청에 대해 실행되게 됩니다. 다만, Exception 파라미터가 null 이 아닐 시 다음 메소드를 실행하여 에러에 대한 적절한 처리가 실행되도록 합니다.)

3. DispatcherServlet - processHandlerException() 해당 디스패쳐 서블릿에 등록된 HandlerExceptionResolver를 순차적으로 적용하여 처리합니다. 이때, 에러가 처리 된다면, 즉시 반환됩니다.

인터셉터의 preHandle(), postHandle(), afterCompletion() 는 정상적으로 요청이 처리됐을때, 모두 실행됩니다.
반면에, 요청 처리 중 에러 발생 시 preHandle(), afterCompletion() 둘만 실행되게 됩니다.

 

즉, 에러 인스턴스들은 HandlerExceptionResolver로 등록된 빈들을 통해 처리 됩니다. 

 

스프링 부트는, HandlerExceptionResolver를 빈으로 등록하여 사용하는 대신, 에러처리를 위한 여러 기본 구성을 제공합니다. 이를 파악하기 위해, WebMvcConfigurationSupport 클래스를 들여다 봅니다.

스프링의 자동구성으로 제공되는 HandlerExceptionResolver 구성 입니다. setOrder를 통해 우선순위를 설정해 해당 빈들을 우선적으로 사용하도록 구현합니다.
자동구성으로 위 사진과 같이 세개의 HandlerExeptionResolver 구현체를 등록하는것을 볼 수 있습니다.

 

위에서 알 수 있듯, 총 세가지 HandlerExceptionResolver가 0 순위로 등록됩니다. 이들은 리스트로 구현되며 리스트에 삽입된 순서로 에러 핸들링이 시작됩니다. 따라서, 0순위이면서도 내부적으로 아래와 같은 처리 순서를 가집니다. 

  1. ExceptionHandlerExceptionResolver
     (1) 먼저, 에러가 발생한 컨트롤러 내에 적합한 @ExceptionHandler이 있으면 그를 실행합니다. 
     (2) 이때 찾지 못하면, @ControllerAdvice의 적절한 @ExceptionHandler를 찾아 그를 실행합니다.
    핸들링 가능한 @ExceptionHandler를 아무것도 찾지 못하면, 다음 리졸버로 에러처리가 위임됩니다.
  2. ResponseStatusExceptionResolver
    에러를 처리할 수 있는 @ExceptionHandler를 찾지 못한 경우, 이 HandlerExceptionResolver로 에러처리가 위임됩니다.
    (1) 먼저, 에러 객체가 ResponseStatusException인지 확인 합니다. 맞다면, 적절한 로직을 수행합니다. 

    (2) 처리되지 못했을때, 에러 객체에 @ResopnseStatus가 붙어있는지를 확인하고, 이에 따라 에러를 처리합니다. 
    (3) 에러 객체가 다른 에러 때문에 발생된 것인지를 확인하고, 해당 함수를 재귀적으로 실행합니다. 이를 통해 더 근본적인 에러를 찾을 수 있습니다. 
    발생된 에러 인스턴스에 ResponseStatusException @ResponseStatus가 없다면, 다음 리졸버로 에러처리가 위임됩니다.
  3. DefaultHandlerExceptionResolver
    (1) 스프링에서 발생된 에러인지를 확인합니다. 
    아닐시 null을 반환하여 다음 리졸버로 넘깁니다. 이 경우, 500대 에러가 발생하게 됩니다. 

ExceptionHandlerExceptionResolver는 처음 등록될떄 위 메소드를 실행합니다. 이를 통해 @ControllerAdvice 어노테이션이 붙은 빈들을 가져오고 이들의 @ExceptionHandler를 저장합니다.

 

ExceptionHandlerExceptionResolver가 실제로 실행될때 적절한 ExceptionHandler를 찾기 위해 호출되는 메소드입니다. 이 메소드를 통해 먼저 컨트롤러 내부에 처리할 수 있는 ExceptionHandler를 찾고, 후에 전역에 걸친(@ControllerAdvice) ExceptionHandler를 찾습니다.
ResponseStatusExceptionResolver의 메소드 입니다. 먼저, 발생한 Exception이 ResponseStatusException, @ResponseStatus를 확인하여 처리하고, 상위 에러가 있을 시, 이에 대해 재귀적으로 처리합니다.

 

 

이상으로 스프링의 에러처리 플로우에 대해 알아봤습니다. 긴글 읽어주셔서 감사합니다 :)

 

'Spring > SpringBoot' 카테고리의 다른 글

Spring boot - Cache (2) 페이지 조회 캐싱  (0) 2025.01.08
Spring boot - Cache  (0) 2025.01.07
[Spring] Spring Security 인증 구성  (0) 2024.01.02
[Spring] 다수의 SecurityFilterChain 구성 방법  (0) 2024.01.01
[Spring] Spring Security Architecture  (1) 2023.12.29
'Spring/SpringBoot' 카테고리의 다른 글
  • Spring boot - Cache (2) 페이지 조회 캐싱
  • Spring boot - Cache
  • [Spring] Spring Security 인증 구성
  • [Spring] 다수의 SecurityFilterChain 구성 방법
윤희종
윤희종
호기심을 잃지 말자 지적, 질문은 언제나 환영합니다 ;)
  • 윤희종
    서버견문록
    윤희종
  • 전체
    오늘
    어제
    • 분류 전체보기 (36)
      • 데일리 플랜 (1)
      • 이것저것 (4)
      • Java (6)
      • Spring (12)
        • SpringBoot (10)
        • Spring MVC (0)
      • Computer Science (4)
        • Network (1)
        • Operating System (0)
        • Data Structure (0)
        • Algorithm (2)
        • Database (0)
      • IOS (0)
      • 프로그래머스 문제풀이 (2)
      • 프로젝트 일기 (7)
        • 한편의 수학 학원 (7)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    SecurityFilterChain
    springboot
    스프링 부트 인증 우회
    스프링 시큐리티 사용법
    Spring
    스프링 부트
    스프링 시큐리티 구성
    인증 우회 테스트
    SecurityFilterChain 구성
    알고리즘
    스프링
    read through
    mysql 쿼리 최적화
    servlet
    제네릭
    캐시
    인증 테스트
    비동기 처리 유의점
    성능 개선
    cache write back
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
윤희종
[SpringBoot] 스프링의 에러처리 탐구
상단으로

티스토리툴바