ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • spring @ControllerAdvice, @ExceptionHandler 예외처리 방법
    Spring/Annotation 2023. 6. 8. 18:02

    @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 에 동작한다.

    반응형

    댓글

Designed by Tistory.