이전 포스팅에서 Spring의 기본적인 예외 처리 방법과 @ControllerAdvice에 대해 알아보았다. 이번에는 이를 활용하여 커스텀 에러를 구현해보도록 하겠다.
가장 먼저 예외 응답을 담아줄 클래스를 정의해준다.
@Getter
@RequiredArgsConstructor
public class ErrorResponse {
private final int code;
private final String message;
}
스펙은 원하는 대로 설정하면 된다. 필자 본인은 도메인별 code를 정하고, message에 에러 내용을 정의한다.
에러 코드들을 정의할 enum 클래스를 만들어 기록한다.
@Getter
@RequiredArgsConstructor
public enum ErrorCode {
COUPON_NOT_FOUND(1000, "존재하지 않는 쿠폰입니다."),
COUPON_ALREADY_USED(1001, "이미 사용한 쿠폰입니다."),
...
MEMBER_NOT_FOUND(3000, "존재하지 않는 사용자입니다.");
private final int code;
private final String message;
}
다음으로는 커스텀 예외 클래스를 정의해주면 된다.
이를 통해 비즈니스 로직 중 ErrorCode로부터 정보를 받아 던지면 된다.
@Getter
public class BadRequestException extends RuntimeException {
private final int code;
private final String message;
public BadRequestException(ErrorCode errorCode) {
this.code = errorCode.getCode();
this.message = errorCode.getMessage();
}
}
마지막으로 전역적으로 예외를 처리하는 GlobalExceptionHandler를 구현하면 된다.
@ExceptionHandler를 통해 커스텀 에러 클래스인 BadRequestException을 잡아 ErrorResponse로 처리해 응답 객체로 처리할 수 있다.
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(BadRequestException.class)
public ResponseEntity<ErrorResponse> handleBadRequestException(BadRequestException exception) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse(exception.getCode(), exception.getMessage()));
}
}