@ControllerAdvice란?

박종하·2025년 9월 10일
post-thumbnail

Spring의 기본 예외 처리

Java에서 try-catch문을 직접 사용해 본 개발자라면, 예외 처리 경험이 썩 유쾌하지만은 않았을 것이다. 다행히 Spring은 기본적인 예외를 처리할 수 있도록 BasicErrorController를 제공한다.

위 그림처럼 컨트롤러에서 발생한 예외는 /error로 리다이렉트되어 BasicErrorController에서 일괄적으로 처리된다. 이때 클라이언트의 요청 헤더에 따라 응답 방식이 달라진다. 즉, 브라우저 요청이라면 HTML 에러 페이지가 내려가고, API 클라이언트 요청이라면 JSON 응답이 내려간다.

  • errorHtml(): html
  • error: json

이때 Json으로 응답을 내려줄 때는 ErrorAttributes의 구현체인 DefaultErrorAttributes에서 정보를 추출해 내려주게 된다.

{
  "timestamp": "2025-09-10T12:34:56.789+00:00",
  "status": 400,
  "error": "Bad Request",
  "message": "Validation failed for object='userRequest'.",
  "path": "/api/users"
}

BasicErrorController로 예외가 가는 흐름

그럼 Controller에서 터진 Error가 어떤 흐름으로 BasicErrorController로 갈까?

  1. 클라이언트에서 받은 요청이 Dispatcher Servlet에서 Handler Mapping을 통해 Controller로 전달된다.
  2. Controller에서 Error 발생.
  3. Dispatcher Servlet에서 이를 캐치해 HandlerExceptionResolver를 탐색한다.(적절한게 없다고 가정)
  4. 찾지 못하고 Servlet Container에 이를 전달한다.
  5. Servlet Container는 Error를 판단해 /error로 요청을 보낸다.
  6. Dispatcher Servlet을 통해 BasicErrorController로 요청을 전달한다.

이 흐름을 보면 Controller와 Servlet Container를 왕복하는 비효율적인 형태가 나타나게 된다.


@ControllerAdvice

HandlerExceptionResolver

위에서 언급한 HandlerExceptionResolver는 Dispatcher Servlet에서 Error를 캐치 시 Error 응답을 만드는 역할을 한다. Error를 캐치하게 되면 모든 HandlerExceptionResolver를 순서대로 탐색해서 적절한 것이 있으면, 이를 통해 처리해 응답을 내려주게 된다. 여기서 중요한 점은 처리가 되면 더 이상 Error가 전파되지 않아, BasicErrorController로 가지 않는다는 점이다.

HandlerExceptionResolver에는 기본적으로 구현체들이 존재한다.

  • ExceptionHandlerExceptionResolver: @ExceptionHandler(처리할 예외 클래스) 에너테이션이 붙어 있는 메소드로 Error 처리.
  • ResponseStatusExceptionResolver: 예외 클래스의 @ResponseStatus(HTTP 상태)의 HTTP 상태 코드로 Error 응답 생성.
  • DefaultHandlerExceptionResolver: 기본 예외를 표준 HTTP 상태로 응답을 생성.

@ControllerAdvice

@ControllerAdvice는 위의 @ExceptionHandler를 매번 작성할 필요없이 전역적으로 사용할 수 있게 해주는 에너테이션이다. 이를 통해 컴포넌트를 새로 작성해 해당 컴포넌트에서 전역적으로 발생하는 Error들을 손쉽게 처리할 수 있게 해준다.

이를 구현하는 예시는 다음 포스팅에서 예제 코드와 함께 설명하겠다.

profile
Ex Pilot, Now Developer

0개의 댓글