Spring

사용자 정의 예외(Custom exception)

초코chip 2024. 3. 25. 19:25

배경

  • 정의: 서버에서 사용자가 부적절한 방식이나 접근을 할 때, 개발자가 직접 예외를 처리하기 위해 사용하는 것
  • 목적: 사용자의 오류를 명확히 알리기 위함. (표준 예외만 발생시키면 정확한 문제를 파악하기 어려움)

 

예외 정의 구조

이 시스템은 다음과 같은 4개의 주요 클래스로 구성됩니다.

 

CustomErrorCode

  • 역할: 에러 코드를 정의하기 위한 enum 클래스 사용.
  • 위치: error/code

 

에러 코드 인터페이스

  • 기능: 모든 에러 코드에 공통적인 인터페이스 정의.
  • 주요 요소: HTTP 상태, 코드, 메시지
public interface ErrorCode {
    String getCode();
    String getMessage();
    HttpStatus getStatus();
}

 

에러 코드 구현

  • 설명: 위 인터페이스를 구현하여 사용자 정의 에러 코드를 작성.
  • 필수 요소:
    • Getter 메소드,
    • 모든 인자를 받는 생성자(AllArgsConstructor)
@Getter
@AllArgsConstructor
public enum BiddingErrorCode implements ErrorCode {
    BIDDING_EXPIRED_PRODUCT(HttpStatus.BAD_REQUEST, "B_001", "이미 입찰 마감된 상품입니다."),
    BIDDING_LOWER_PRICE(HttpStatus.BAD_REQUEST, "B_002", "현재 가격이 기존 최고 가격보다 낮습니다."),
    BIDDING_INSUFFICIENT_BID(HttpStatus.BAD_REQUEST, "B_003", "입찰 가격과 기존 최고 가격의 차이가 최소 단위보다 작습니다.");

    private final HttpStatus status;
    private final String code;
    private final String message;
}

 

CustomException

  • 정의: ErrorCode를 포함하는 클래스 정의.
  • 위치: error/exception
  • 필수 요소:
    • RuntimeException을 상속
    • ErrorCode를 받아 처리
@Getter
public class CustomException extends RuntimeException {
    private final ErrorCode errorCode;
    private final HttpStatus status;

    public CustomException(ErrorCode errorCode) {
        super(errorCode.getMessage());
        this.errorCode = errorCode;
        this.status = errorCode.getStatus();
    }
}

 

CustomExceptionHandler

  • 정의: 컨트롤러 전역에서 발생하는 사용자 정의 예외를 처리하는 핸들러.
  • 위치: error/handler
  • 구성:
    • @RestControllerAdvice를 사용하여 모든 RestController에서 발생할 수 있는 예외를 캐치.
    • @ExceptionHandler(CustomException.class)로 발생한 CustomException 예외를 공통적으로 처리.
    • @Slf4j로 예외에 대한 로그 출력.
@RestControllerAdvice
@Slf4j
public class CustomExceptionHandler {

    @ExceptionHandler(CustomException.class)
    public ResponseEntity<ErrorResponse> handle(CustomException e) {
        ErrorCode errorCode = e.getErrorCode();
        log.warn("code = {}, message = {}", errorCode.getCode(), errorCode.getMessage());

        return ResponseEntity.status(e.getStatus()).body(ErrorResponse.from(errorCode));
    }
}

 

ErrorResponseDto

  • 정의: 사용자 정의 에러의 내용을 담을 응답 DTO 생성.
  • 위치: error/response
public record ErrorResponse(
        String code,
        String message
) {
    public static ErrorResponse from(ErrorCode errorCode) {
        return new ErrorResponse(errorCode.getCode(), errorCode.getMessage());
    }
}

 

 

예외 사용

이제 작성한 에러코드르 가지고 Service단에서 예외를 발생시킬 때, CustomException을 발생시키자!

//Service 메서드
    public MemberResponse findById(Long id) {
        Member member = memberRepository.findById(id)
                .orElseThrow(() -> new CustomException(MEMBER_NOT_EXIST));

        return MemberResponse.from(member);
    }

'Spring' 카테고리의 다른 글

스프링 파일 첨부 요청 처리  (0) 2024.02.07