[1년 후 마실가실] Custom Error 처리
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