반응형

@ExceptionHandler

@ExceptionHandler  @Controller , @RestController 가 적용된 Bean 에서 발생하는 예외를 잡아서 하나의 메서드에서 처리해주는 기능이다. @ExceptionHandler 에 설정한 예외가 발생하면 handler가 실행된다. 

 

@RestController
public class MyRestController {
    ...
    ...
    @ExceptionHandler(NullPointerException.class)
    public Object nullex(Exception e) {
        System.err.println(e.getClass());
        return "myService";
    }
}

위와 같이 적용하기만 하면 된다. @ExceptionHandler라는 어노테이션을 쓰고 인자로 캐치하고 싶은 예외클래스를 등록해주면 끝난다.

→ @ExceptionHandler({ Exception1.class, Exception2.class}) 이런식으로 두 개 이상 등록도 가능하다.

위의 예제에서 처럼하면 MyRestController에 해당하는 Bean에서 NullPointerException이 발생한다면, @ExceptionHandler(NullPointerException.class)가 적용된 메서드가 호출될 것이다.

 

주의사항/알아 둘 것

  • Controller, RestController에만 적용가능하다. (@Service같은 빈에서는 안됨.)
  • 리턴 타입은 자유롭게 해도 된다. (Controller내부에 있는 메서드들은 여러 타입의 response를 할 것이다. 해당 타입과 전혀다른 리턴 타입이어도 상관없다.)
  • @ExceptionHandler를 등록한 Controller에만 적용된다. 다른 Controller에서 NullPointerException이 발생하더라도 예외를 처리할 수 없다. -> controllerAdvice 와 같이 사용하면 됨.
  • 메서드의 파라미터로 Exception을 받아왔는데 이것 또한 자유롭게 받아와도 된다.

 

 

@ControllerAdvice

@ExceptionHandler가 하나의 클래스에 대한 것이라면, @ControllerAdvice는 모든 @Controller 즉, 전역에서 발생할 수 있는 예외를 잡아 처리해주는 annotation이다.

 

@RestControllerAdvice
public class MyAdvice {
    @ExceptionHandler(CustomException.class)
    public String custom() {
        return "hello custom";
    }
}

 

종합적으로 @ExceptionHandler 와 @ControllerAdvice 같이 사용하여야 한다.

@RestControllerAdvice
@RequiredArgsConstructor
public class CommonExceptionAdvice {

    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<ErrorResponse> runtimeException(Exception e) {
        ErrorResponse errorResponse = new ErrorResponse(CustomExceptionCode.ERROR_500);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(errorResponse);
    }

    @ExceptionHandler(CustomException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<ErrorResponse> customException(Exception e) {
        ErrorResponse errorResponse = new ErrorResponse(CustomExceptionCode.ERROR_500);

        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(errorResponse);
    }
 }

위와 같이 특정 Exception 에 대해 응답 코드를 달리해서 처리하면 좋다.

ControllerAdvice 와 같이 사용하면 sevice 레벨에서 예외가 발생해도 handler 에 동작한다.

반응형

+ Recent posts