@ExceptionHandler

yookyungmin·2023년 6월 8일
0

HTML 화면 오류 VS API오류

  • 웹 즈라우저에 HTML화면을 제공할 떄는 오류가 발생하면 BasicErrorController를 사용하는게 편하다
  • 이 때는 단순히 5XX, 4XX 관련된 오류 화면을 보여주면 된다.
  • BasicErrorController나 HandlerExceptionResolver는 직접 구현하는 방식으로 api 예외를 다루기 쉽지 않다

API 예외처리의 어려운점

  • HandlerExceptionResolver는 ModelAndView를 반환하는데 API 응답에는 필요하지 않다.
  • 특정 컨트롤러에서만 발생하는 예외를 별도로 처리하기 어렵다. RuntimeException 예외를 서로 다른 방식으로 처리하고 싶다면 어떻게 해야 할까

@ExceptionHandelr

  • 스프링은 API 예외처리 문제를 해결하기 위해 매우 편리한 예외처리 기능을 제공하는 어노테이션.스프링은 ExceptionHandlerExceptionResolver 를 기본으로 제공하고 기본으로 제공하는 ExceptionResolver중에 우선순위도 가장 높다. 실무에서 API 예외처리는 대부분 이 기능을 제공한다.

@ExceptionHandler 예외처리 방법

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

우선 순위

  • 스핑의 우선순위는 항상 자세한 것이 우선권을 가진다 예를 들어서 부모, 자식 클래스가 있꼬 다음과같이 예외가 처리된다
    @ExceptionHandler에 지정된 부모클래스는 자식 클래스까지 처리할수 있다.
    따라서 자식 예외가 발생하면 부모예외처리(), 자식예외처리() 둘다 호출 대상이된다. 그런데 둘중 더 자세한 것이 우선권을 가지므로 자식예외처리()가 호출된다.
@ExceptionHandler(부모예외.class)
public String 부모예외처리(부모예외 e) {
}
@ExceptionHandler(자식.class)
public String 자식예외처리(자식예외 e) {
}

@ExceptionHandler에 지정된 부모클래스는 자식 클래스까지 처리할수 있다.
따라서 자식 예외가 발생하면 부모예외처리(), 자식예외처리() 둘다 호출 대상이된다. 그런데 둘중 더 자세한 것이 우선권을 가지므로 자식예외처리()가 호출된다.

다양한 예외

@ExceptionHandler({AException.Class, BException.class)
public String ex(Exception e) {
	log.info("exception", e);
}

다음과 같이 다양한 예외를 한번에 처리할 수 있다.

예외 생략

 @ExceptionHandler
    public ResponseEntity<ErrorResult> userExHandler(UserException e){
            log.error("[exceptionHandler", e);
        ErrorResult errorResult = new ErrorResult("user-ex", e.getMessage());
        return  new ResponseEntity(errorReuslt, HttpStatus.BAD_REQUEST)
    }

메서드의 파라미터에 예외가 지정된다.

실행 흐름

@ResponseStatus(HttpStatus.BAD_REQUEST) //처리가 완료되면 200인데 오류를 지정
  @ExceptionHandler(IllegalArgumentException.class)
  public ErrorResult illeagalExHandler(IllegalArgumentException e){
      log.error("[ExceptionHandler ex", e);
      return  new ErrorResult("Bad", e.getMessage());
  }
  • 컨트롤러를 호출한 경과 IllegalArgumentException 예외가 컨트롤러 밖으로 던져진다.
  • 예외가 발생으므로 ExceptionResolver가 작동한다. 가장 우선순위가 높은 ExceptionHandlerExceptionResolver가 실행된다.
  • ExceptionHandlerExceptionResolver는 해당 컨트롤러에 IllegalArgumentException을 처리할 수 있는
    @ExceptionHandler가 있는지 확인한다.
  • IllegalExHandel()실행한다 @RestController이므로 IllegalExHandler에도 @ResponseBody가 적용된다. 따라서 HTTP 컨버터가 사용되고 응답이 다음과 같은 JSON 을 반환된다.
  • @ResoponseStatus(HttpStatus.BAD_REQUEST)를 지정 했으므로 HTTP 상태코드 400으로 응답된다.
    json
    {
    "code" : "BAD",
    "message":"잘못된 입력"
    }

0개의 댓글