BACK/SPRING

[Spring] @ExceptionHandler를 사용해 예외 처리하기

연듀 2024. 4. 18. 16:40

 

 

스프링은 API 예외 처리 문제를 해결하기 위해 @ExceptionHandler를 사용한 편리한 예외 처리 기능을 제공한다.

 

다음은 진행하고 있는 프로젝트에 @ExceptionHandler를 적용한 코드이다.

 

@Getter
@AllArgsConstructor
public enum ErrorCode {
    // 400
    NOT_SELECTED_TAG(BAD_REQUEST, "수거함 태그는 반드시 한 개 이상 설정해야 합니다.");

    // 404

    // 409

    // 500

    private final HttpStatus httpStatus;
    private final String message;
}

 

enum 클래스를 만들어 상태 코드와 메세지를 담은 열거형을 정의한다. 

@Getter
public class CollectingBoxException extends RuntimeException {
    private final ErrorCode errorCode; // 발생한 오류 코드

    public CollectingBoxException(ErrorCode errorCode) {
        super(errorCode.getMessage()); // 해당 예외의 메시지 설정
        this.errorCode = errorCode;
    }
}

 

 

RuntimeException을 상속받은 클래스를 작성한다.

 

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(CollectingBoxException.class)
    public ResponseEntity<ErrorResponse> handleCollectingBoxException(CollectingBoxException e) {
        ErrorResponse errorResponse = ErrorResponse.from(e.getErrorCode());
        log.error("exception message = {}", e.getMessage());
        return ResponseEntity.status(errorResponse.getHttpStatus()).body(errorResponse);
    }
}

 

@ExceptionHandler를 선언하고, 괄호 안에 처리하고 싶은 예외를 지정해주면 된다.

컨트롤러에서 해당 예외가 발생하면 이 메서드가 호출한다.

 

@RestControllerAdvice는 @ControllerAdvice에 @ResponseBody가 추가된 것으로,

@ControllerAdvice는 대상으로 지정한 여러 컨트롤러에 @ExceptionHandler 기능을 부여해주는 역할을 한다.

이 코드에서는 대상 컨트롤러 지정을 생략하여 모든 컨트롤러에 적용이 된다.

 

 

@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class ErrorResponse {

    private HttpStatus httpStatus;
    private String message;

    public static ErrorResponse from(ErrorCode errorCode) {
        return new ErrorResponse(errorCode.getHttpStatus(), errorCode.getMessage());
    }
}