반응형

API 예외 처리 - 스프링이 제공하는 ExceptionResolver1


스프링 부트가 기본으로 제공하는 ExceptionResolver는 다음과 같다.
HandlerExceptionResolverComposite에 다음 순서로 등록

  1. ExceptionHandlerExceptionResolver
  2. ResponseStatusExceptionResolver
  3. DefaultHandlerExceptionResolver → 우선 순위가 가장 낮다.


ExceptionHandlerExceptionResolver
@ExceptionHandler을 처리한다. API 예외 처리는 대부분 이 기능으로 해결한다.  조금 뒤에 자세히 설명한다.

ResponseStatusExceptionResolver
HTTP 상태 코드를 지정해준다.
예) @ResponseStatus(value = HttpStatus.NOT_FOUND)


DefaultHandlerExceptionResolver
스프링 내부 기본 예외를 처리한다.

먼저 가장 쉬운 ResponseStatusExceptionResolver 부터 알아보자.

 

ResponseStatusExceptionResolver
ResponseStatusExceptionResolver는 예외에 따라서 HTTP 상태 코드를 지정해주는 역할을 한다.

다음 두 가지 경우를 처리한다.

  • @ResponseStatus 가 달려있는 예외
  • ResponseStatusException 예외

하나씩 확인해보자.

예외에 다음과 같이 @ResponseStatus 애노테이션을 적용하면 HTTP 상태 코드를 변경해준다.

BadRequestException 예외가 컨트롤러 밖으로 넘어가면 ResponseStatusExceptionResolver 예외가 해당 애노테이션을 확인해서 오류 코드를 HttpStatus.BAD_REQUEST(400)으로 변경하고, 메시지도 담는다.

ResponseStatusExceptionResolver 코드를 확인해보면 결국 response.sendError(statusCode, resolverReason)를 호출하는 것을 확인할 수 있다. sendError(400)를 호출했기 때문에 WAS에서 다시 오류 페이지(/error)를 내부 요청한다.



ApiExceptionController - 추가

실행 (실행하기 전에 application.properties에 server.error.include-message=always 를 추가하자.)
http://localhost:8080/api/response-status-ex1


메시지 기능
reasonMessageSource에서 찾는 기능도 제공한다. reason = "error.bad"


messages.properties


메시지 사용 결과

 


ResponseStatusException
@ResponseStatus는 개발자가 직접 변경할 수 없는 예외에는 적용할 수 없다. (애노테이션을 직접 넣어야 하는데, 내가 코드를 수정할 수 없는 라이브러리의 예외 코드 같은 곳에는 적용할 수 없다.)
추가로 애너테이션을 사용하기 때문에 조건에 따라 동적으로 변경하는 것도 어렵다.
이때는 ResponseStatusException 예외를 사용하면 된다.

public ResponseStatusException(
  HttpStatus status, 
  @Nullable String reason, 
  @Nullable Throwable cause
) {}

아래와 같은 파라미터가 있다.

  • status : HTTP Status
  • reason : HTTP response Message
  • cause : ResponseStatusException 을 발생시킨 Exception

스프링에서는 HandlerExceptionResovler가 모든 exception을 가로채서 처리한다.
이중에서 ResponseStatusExceptionResolver라는 클래스가 ResponseStatusException또는 @ResponseStatus 애너테이션이 붙은 Exception을 찾아서 처리해준다.


ApiExceptionController - 추가

http://localhost:8080/api/response-status-ex2

NOT_FOUND 는 404인데 404오류로 잘 처리된 것을 확인할 수 있다.

반응형