API 예외처리 (@ExceptionHandler)

bagt13·2022년 8월 13일
0

Spring

목록 보기
5/12

스프링 부트가 기본으로 제공하는 ExceptionResolver 는 여러 가지가 있는데,
HandlerExceptionResolverComposite 에 다음 순서로 등록되어 있다.

  1. ExceptionHandlerExceptionResolver

  2. ResponseStatusExceptionResolver

  3. DefaultHandlerExceptionResolver (우선 순위가 가장 낮다)


ExceptionHandlerExceptionResolver : @ExceptionHandler을 처리한다. API 예외처리는 이 방식을 가장 많이 사용한다.

ResponseStatusExceptionResolver : HTTP 상태 코드를 지정해준다.

ex) @ResponseStatus(value = HttpStatus.NOT_FOUND)

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


@ExceptionHandler

예외 처리 메서드에 @ExceptionHandler 애노테이션을 선언하고, 해당 컨트롤러에서 처리하고 싶은 예외를 지정해주면 된다. 해당 컨트롤러에서 예외가 발생하면 해당 메서드가 호출된다.

  • RuntimeException을 던지면 결국 컨트롤러까지 올라오기 때문에 컨트롤러에서 예외를 잡으면 된다.

  • (참고로 지정한 예외 또는 그 예외의 자식 클래스는 모두 처리할 수 있으며, 다양한 예외를 한번에 처리할 수 있다)

위의 경우, ConstraintViolationException 예외가 컨트롤러에서 발생할 경우, 이 메서드가 호출된다.

@ExceptionHandler 애노테이션의 속성에 처리할 예외를 명시해도 되고, 생략할 경우에 파라미터의 예외가 지정된다.


@ControllerAdvice와 @RestControllerAdvice

  • @ControllerAdvice 또는 @RestControllerAdvice를 사용하면, 위에서 작성한 예외처리 로직(@ExceptionHandler)들을 한 곳에 모아서 관리할 수 있다.
  • 또한, 대상 컨트롤러를 지정하여 여러 컨트롤러에 @ExceptionHandler, @InitBinder 기능을 부여해주는 역할을 한다.
    (대상 컨트롤러 지정의 경우, 특정 패키지/클래스를 지정하거나 특정 애노테이션이 있는 컨트롤러를 직접 지정할 수도 있다)

    대상을 지정하지 않을 경우 모든 컨트롤러에 적용된다 (글로벌 적용)

  • @RestControllerAdvice 는 @ControllerAdvice 와 같고, @ResponseBody가 추가되어 있다


여기서는 ErrorResponse라는 에러 응답 클래스를 만들어 ResponseEntity로 응답을 내렸다.

ErrorResponse


전체 실행 흐름

  1. 컨트롤러를 호출한 결과 custom 예외 클래스인 BusinessLogicException 예외가 컨트롤러 밖으로 던져진다.

  2. 예외가 발생했으로 ExceptionResolver 가 작동한다. 가장 우선순위가 높은
    ExceptionHandlerExceptionResolver 가 실행된다.

  3. ExceptionHandlerExceptionResolver 는 해당 컨트롤러에 BusinessLogicException 을 처리할 수 있는 @ExceptionHandler 가 있는지 확인한다.

  4. handleBusinessLogicException() 를 실행한다. @RestController 이므로 handleBusinessLogicException() 에도 @ResponseBody 가 적용된다.
    따라서 HTTP 컨버터가 사용되고, 응답이 JSON으로 반환된다.

profile
주니어 백엔드 개발자입니다😄

0개의 댓글