스프링 미니 프로젝트 - 예외 처리 (Custom Exception)

Zyoon·2025년 5월 22일

미니프로젝트

목록 보기
11/35
post-thumbnail

📘Custom Exception을 활용하여 에러 메세지를 직접 남겨준다.


0. Custom Exception 사용 이유

  • 예외가 발생했을 때, 상태 코드만 보고는 어떤 상황인지 정확하게 파악이 불가능하다.
  • 그러므로 상황에 맞는 ****HTTP 상태 코드를 임의로 전달하여 정확한 예외 내용을 알려준다.
  • 의미 있는 오류 메시지를 전달하여 오류에 대한 상황을 명확하게 할 수도 있다.
  • 정확한 오류 발생 지점을 추적할 수 있으며, 추가 정보 저장도 가능하다.

1. ENUM 생성

  • 전달하고자 하는 오류 메세지를 ENUM 으로 관리하기 위해 ENUM클래스를 만들어 준다.
@Getter
@AllArgsConstructor
public enum ErrorCode {

    USER_ALREADY_EXISTS(HttpStatus.CONFLICT, "이미 존재하는 사용자입니다."),
    USER_NOT_FOUND(HttpStatus.NOT_FOUND, "유저 정보가 없습니다.");
    
    private final HttpStatus httpStatus
    private final String message;
}

2. 클래스 생성

  • 우선 CustomException 클래스를 생성해준다.
  • RuntimeException을 상속받는다.
  • 해당 클래스로 위에서 생성한 ENUM 객체를 넘겨준다.
@Getter
public class CustomException extends RuntimeException{
    private final HttpStatus status;

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

3. DTO 생성

  • 예외를 전달할 Dto 를 생성해준다.
  • status 는 상태코드의 int 값만 받기 위해 int로 선언해준다.
  • 예외가 발생한 위치를 넘기기 위해 location 도 만들어준다.
@Getter
public class ExceptionDto {
    private final int status;
    private final String message;
    private final String location;

    public ExceptionDto(HttpStatus status, String message, String location) {
        this.status = status.value();
        this.message = message;
        this.location = location;
    }
}

4. Exception Handler

  • 전역 예외 처리기를 생성해준다.
  • @RestControllerAdvice를 통해 @ExceptionHandler 메서드를 등록하여, API 내의 예외들을 일괄 처리할 수 있도록해준다.
  • 이 상태로는 Custom 예외만 처리하고 있지만, CustomException으로 직접 날릴 수 없는 예외들은 따로 지정하여 처리가 가능하다.
  • 예외 메세지는 DTO 에 담겨 JSON 방식으로 호출된다.
@RestControllerAdvice
public class GlobalExceptionHandler{

		//다른 예외도 등록하여 처리가 가능하다.
   @ExceptionHandler(CustomException.class)
    public ResponseEntity<ExceptionDto> handleCustomException(CustomException e){
        String location = getExceptionOccurredLocation(e);
        ExceptionDto exceptionDto = new ExceptionDto(e.getStatus(), e.getMessage(), location);
        return ResponseEntity.status(e.getStatus()).body(exceptionDto);
    }
    
    //location 구하는 메서드
    private String getExceptionOccurredLocation(Throwable e) {
        if (e == null || e.getStackTrace().length == 0) return "Unknown Location";
        StackTraceElement element = e.getStackTrace()[0];
        String className = element.getClassName().substring(element.getClassName().lastIndexOf('.') + 1);
        return className + "." + element.getMethodName() + " :: Line " + element.getLineNumber();
    }
}

5. 사용 예시

  • 예외 처리가 필요한 곳에 CustomException을 생성해 준다.
User user = userRepository.findById(id)
    .orElseThrow(()-> new CustomException(ErrorCode.USER_NOT_FOUND));
  • 404 Not Found 에러와 함께 DTO 타입으로 전달된 객체가 JSON 방식으로 반환된다.

profile
기어 올라가는 개발

0개의 댓글