API 예외 처리

KJH·2023년 2월 13일

SpringMVC2

목록 보기
10/12

시작

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 부여해줌
  • 컨트롤러, 패키지를 직접 지정 가능 (지정안하면 전부)

0개의 댓글