PlayGround/마실가실 리팩토링

[1년 후 마실가실] Custom Error 처리

HJ0216 2024. 9. 17. 10:25

1년 전 진행했던 마실가실 프로젝트를 🛠️리팩토링하며 정리한 내용입니다.

 

사실 제 코드에는 숨겨진 비밀이 있었습니다😮.

 

그간 throw new BusinessException을 썼지만, 정작 Postman을 통해 api 테스트를 하고, Exception을 발생시켜보면 500 Error가 발생합니다.

 

제 프로그램은 client의 잘못도 server가 떠안는 구조이기 때문입니다,,^^,,

 

농담이고, JWT 로그아웃까지 구현된 지금 Error Code 반환을 처리해보면 좋을 것 같아 정리해봅니다.

 

ErrorCode.java
@Getter
public enum ErrorCode {
    // 회원
    DUPLICATED_EMAIL(HttpStatus.BAD_REQUEST, "이미 존재하는 이메일 입니다."),
    NOT_EQUAL_PASSWORD(HttpStatus.BAD_REQUEST,"입력한 비밀번호가 상이합니다."),
    CHECK_LOGIN_ID_OR_PASSWORD(HttpStatus.NOT_FOUND, "아이디 또는 비밀번호를 확인해주세요."),
    NOT_FOUND_MEMBER(HttpStatus.NOT_FOUND, "존재하지 않는 회원입니다."),
    LOGOUT_MEMBER(HttpStatus.NOT_FOUND, "로그아웃한 회원입니다."),
    INVALID_ACCESS_TOKEN(HttpStatus.NOT_FOUND, "유효하지 않은 Access Token입니다."),
    INVALID_REFRESH_TOKEN(HttpStatus.NOT_FOUND, "유효하지 않은 Refresh Token입니다.")
    ;
    
    private final HttpStatus httpStatus;
    private final String message;

    ErrorCode(HttpStatus httpStatus, String message) {
        this.httpStatus = httpStatus;
        this.message = message;
    }
}

필요한 ErrorCode를 Enum 타입으로 선언해둡니다.

Enum은 단순히 값대신 문자열만 쓰는 줄 알았는데, 인스턴스처럼 쓸 수도 있었습니다.

 

📝 예시

ErrorCode errorCode = ErrorCode.NOT_FOUND_AUTHORITY;
HttpStatus status = errorCode.getStatus();
String message = errorCode.getMessage();

System.out.println("Status: " + status); // 출력: Status: 404 NOT_FOUND
System.out.println("Message: " + message); // 출력: 존재하지 않는 권한입니다.

 

BusinessException.java
@Getter
@RequiredArgsConstructor
public class BusinessException extends RuntimeException{
    private final ErrorCode errorCode;
}

Error Code를 사용할 RuntimeException을 상속받은 BusinessException을 선언합니다.

 

 

여기까지만 구현하면, 고객님들에게 응답을 들려드릴 수 없기에 Response도 구현해두어야 합니다.

 

ErrorResponse.java
@Getter
public class ErrorResponse {
    private String errorMessage;

    public static ResponseEntity<ErrorResponse> toResponseEntity(ErrorCode errorCode) {
        return ResponseEntity.status(errorCode.getHttpStatus())
                .body(ErrorResponse.builder()
                    .errorMessage(errorCode.getMessage())
                    .build());

    }
}

 

Reponse를 구현했으면, 전역 예외 처리가 필요합니다.

이를 위해 @RestControllerAdvice를 사용해 예외를 처리하는 핸들러를 추가해야 합니다.

 

GlobalExceptionHandler.java
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<ErrorResponse> businessExceptionHandler(BusinessException e) {
        return ErrorResponse.toResponseEntity(e.getErrorCode());
    }
}

이렇게 서버는 과중한 책임에서 벗어나 400 에러도 반환할 수 있게 되었습니다.

 

 

 

🙋‍♀️

본 포스트는 공부 목적으로 작성하였습니다.
보시는 도중 잘못된 부분이나 개선할 부분이 있다면 댓글로 알려주시면 수정하도록 하겠습니다.

 

📑

참고 자료

https://github.com/dbswhd4932/shoppingmall_project

 

GitHub - dbswhd4932/shoppingmall_project: Java Springboot Jpa 를 이용한 쇼핑몰 API 프로젝트

Java Springboot Jpa 를 이용한 쇼핑몰 API 프로젝트. Contribute to dbswhd4932/shoppingmall_project development by creating an account on GitHub.

github.com