Skip to main content

API 예외 처리

·232 words·2 mins· loading
Table of Contents
SpringMVC2 - This article is part of a series.
Part 10: This Article

시작
#

HTML은, 오류가 나면 4xx,5xx 오류 페이지만 있으면 된다. 근데, API의 경우에는 각 오류 상황에 맞는 응답 스펙을 정하고, json으로 줘야됨

ex)

@RequestMapping(value="/error-page/500",produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Map<String, Object>> errorPage500Api(HttpServletRequest request , HttpServletResponse response){

        Map<String, Object> result = new HashMap<>();
        Exception ex = (Exception) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
        result.put("status",request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE));
        result.put("message", ex.getMessage());

       Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
       return new ResponseEntity<>(result, HttpStatus.valueOf(statusCode));
    }

요청의 Acceptapplication/json인 경우를 처리 HttpRequest의 정보를 토대로 json 생성 후 반환 이전글 참고

API 처리시 가장 좋은 방법은 ExceptionHandler 사용이다


HandlerExceptionResolver
#

발생하는 예외에 따라서 각각 처리하고 싶다면?

  • ex) IllegalArgumentEsxeption을 처리하지 못하면, 400으로 처리하고싶음

HandlerExceptionResolver 컨트롤러 밖으로 던져진 예외를 해결하고, 동작 방식을 변경 Was가 에러 페이지를 찾아서 다시 제공하지 않고, 정상응답 줄여서 ExceptionResolver


스프링 부트가 제공하는 ExceptionReoslver
#

  1. ExceptionHandlerExceptionResolver (가장 중요하므로 따로다룸)
  2. ResponseStatusExceptionResolver
  3. DefaultHandlerExceptionResolver (마지막우선순위)

ResponseStatusExceptionResolver 예외에 따라서 HTTP 코드 지정 내부적으로 response.sendError()호출 ex) @responseStatus가 달려있는 예외 또는 ResponseStatusException

@ResponseStatus(code= HttpStatus.BAD_REQUEST,reason = "잘못된 요청 오류")
public class BadRequestException extends RuntimeException{}

**DefaultHandlerExceprtionResolver ** 스프링 내부 예외 해결 (TypeMismatchException 등) 내부적으로 response.sendError()호출


@ExceptionHandler
#

ExceptionHandlerExceptionResolver 사용 우선순위도 가장 높고, 실무에서 API 예외 처리 시 거의 이것만 사용

@ExceptionHandler 어노테이션을 선언하고, 예외를 지정해주면 해당 컨틀롤러에서 해당 예외(자식도)가 발생하면 이 메서드가 호출됨. (컨트롤러와 비슷하게 동작함)

ex)

 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ExceptionHandler(IllegalArgumentException.class)
  public ErrorResult illegalExHandler(IllegalArgumentException e){
    log.error("[exceptionHandler] ex",e);
     return new ErrorResult("BAD",e.getMessage());
    }

스프링의 우선순위는 항상 자세한 것이 우선권을 가짐 공식문서


@ControllerAdvice
#

정상 처리와 예외 처리 코드를 분리

  • 대상으로 지정한 여러 컨트롤러에 @ExceptionHandler,@InitBuilder 부여해줌
  • 컨트롤러, 패키지를 직접 지정 가능 (지정안하면 전부)

SpringMVC2 - This article is part of a series.
Part 10: This Article