Spring

Spring Boot 3.2에서 달라진 예외 처리 방식 - NoHandlerFoundException도 @ControllerAdvice로 처리된다.

va-la 2025. 5. 8. 23:03

Spring Boot 2에서 3으로 마이그레이션 하면서 작지만 중요한 변화 하나를 발견했다. 바로 요청 URL에 해당하는 핸들러(Controller)가 존재하지 않을 때의 예외 처리 방식이 변경된 것이다.

기존(Spring Boot 2.x ~ Spring Boot 3.1)의 동작 방식

Spring Boot 2.x 버전에서는 존재하지 않는 경로로 요청할 경우, @ControllerAdvice에 선언된 @ExceptionHandler(Exception.class)가 동작하지 않았다. 대신 Spring 자체의 오류 처리 페이지(resources/templates/error/4xx.html)가 렌더링 되었다.

ResourceHttpRequesrHandler

 

변경 사항(Spring Boot 3.2부터)

Spring Boot 3.2부터는 NoHandlerFoundException도 @ControllerAdvice의 @ExceptionHandler로 전달되어 처리할 수 있게 되었다. (관련 이슈: https://github.com/spring-projects/spring-boot/issues/38733)

ResourceHttpRequesrHandler


 

실습으로 비교해 보자

공통 설정

 
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'org.springframework.boot:spring-boot-starter-web'
}
  • /templates/index.html → 정상 페이지
  • /templates/error/4xx.html → 오류 페이지
  • '/' 요청을 처리하는 TestController
  • Exception을 처리하는 GlobalExceptionHandler
// Controller
@Controller
public class TestController {
    @GetMapping("/")
    public String index() {
        return "index";
    }
}

// ExceptionHandler
@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public String handleException(Exception e) {
	System.out.println(e);
        
        return "index";
    }
}

1. Spring Boot 3.1.9에서의 동작

  • '/' 요청 → index.html 정상 출력

index.html

  • '/abcd' 요청 → 존재하지 않는 경로 → 4xx.html 렌더링 됨
    → GlobalExceptionHandler는 호출되지 않음

4xx.html

즉, Spring 내부 오류 처리로 빠진다.


2. Spring Boot 3.2.5에서의 동작

  • /abc 요청 시 → GlobalExceptionHandler가 호출됨

GlobalExceptionHandler

  • 디버깅 결과: NoResourceFoundException 발생

NoResourceFoundException

  • 결과적으로 index.html이 렌더링 됨

index.html

즉, 이제는 존재하지 않는 경로도 개발자가 정의한 글로벌 핸들러에서 처리할 수 있게 되었다.


정리 및 주의사항

  • Spring Boot 3.2부터는 NoHandlerFoundException (또는 내부적으로 던지는 NoResourceFoundException)도 @ControllerAdvice로 처리 가능하다.
  • 기존에는 4xx.html, 5xx.html 등으로 구분해 템플릿 렌더링했지만, 이제는 글로벌 예외 처리에 걸리기 때문에 기대했던 템플릿이 아닌 다른 뷰가 렌더링 될 수 있다.
  • 따라서 마이그레이션 시, @ControllerAdvice의 ExceptionHandler가 모든 예외를 catch 하고 있는지 확인하고, 특정 예외만 처리하도록 조건을 걸어두는 것이 좋다.

'Spring' 카테고리의 다른 글

@Transactonal  (1) 2023.05.11
Maven  (0) 2021.06.19