suyeonme

[Spring Boot] @ControllerAdvice, @ExceptionHandler로 Exception Handling하기 본문

프로그래밍👩🏻‍💻/Spring

[Spring Boot] @ControllerAdvice, @ExceptionHandler로 Exception Handling하기

suyeonme 2023. 1. 10. 22:38

@ControllerAdvice, @ExceptionHandler란?


@ControllerAdvice

@Controller(+@RestController)가 적용된 모든 스프링빈에서 발생하는 예외를 잡아서 처리해주는 어노테이션이다.

 

아래 예시처럼 {NullPointerException.class, UserServiceException.class}와 같이 여러 클래스를 함께 정의할 수도 있고 단일 클래스만 정의할 수도 있다. 아래와 같이 작성한 경우, 모든 컨트롤러에서 NullPointerException 또는 UserServiceException 커스텀 예외가 발생하는 경우, 아래 클래스가 예외를 잡아서 처리한다. 

 

ErrorMessage 클래스처럼 에러 메세지를 위한 객체를 생성한 뒤 클라이언트에 일관된 에러를 응답에 담아 반환하는 것이 일반적이다.

@ControllerAdvice
public class AppExceptionsHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler(value = {NullPointerException.class, UserServiceException.class})
    public ResponseEntity<Object> handleNullPointerException(Exception ex, WebRequest request) {
        String errorMessageDescription = ex.getLocalizedMessage();
        if(errorMessageDescription == null) {
            errorMessageDescription = ex.toString();
        }

        ErrorMessage errorMessage = new ErrorMessage(new Date(), errorMessageDescription);
        return new ResponseEntity<>(
                errorMessage,
                new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR
        );
    }
}

// ErrorMessage.class
@Getter
@Setter
public class ErrorMessage {
    private Date timestamp;
    private String message;

    public ErrorMessage() {}

    public ErrorMessage(Date timestamp, String message) {
        this.timestamp = timestamp;
        this.message = message;
    }
}

@ExceptionHandler

@Controller(+@RestController)가 적용된 스프링빈에서 발생하는 예외를 잡아서 하나의 메서드에서 처리해주는 어노테이션이다.

@ExceptionHandler(value = {Exception.class})
public ResponseEntity<Object> handleAnyException(Exception ex, WebRequest request) {
  String errorMessageDescription = ex.getLocalizedMessage();
    if(errorMessageDescription == null) {
      errorMessageDescription = ex.toString();
    }

  ErrorMessage errorMessage = new ErrorMessage(new Date(), errorMessageDescription);
    return new ResponseEntity<>(
      errorMessage,
      new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR
    );
}

Custom Exception 생성하기

아래와 같이 필요에따라 Custom Exception을 작성할 수 있다.

// UserServiceException.class
public class UserServiceException extends RuntimeException {

    private static final long serialVersionUID = -7557185871786744152L;

    public UserServiceException(String message) {
        super(message);
    }
}

// UserController.class
public class UserController {
 public ResponseEntity<UserResponse> createUser(@Valid @RequestBody UserDetailRequest userRequest) {
   if(//...) {
     throw new UserServiceException("This is UserServiceException!");
   }
 }
}

 

 

 

Comments