What I learned while coding
말 그대로, 내가 코딩을 하면서 배운 것 💻
내가 일을 하든, 사이드 프로젝트를 하든, 배운 모든 것들을 적어볼 생각이다 (미래의 내가 다시 보기 위해)
API 호출 시에는 일관된 응답을 보내주어야 한다.
그것은 로직이 정상적으로 진행되었든, 오류가 발생했든 동일해야 할 것이다.
그래서 응답을 표준화 하게 되는데.....
이번 시간에는 로직 처리 중 오류 시 리턴되는 오류 형식을 표준화 하고 내가 원하는 오류 메시지를 리턴할 수 있게끔 처리하는 방법에 대해 정리해보겠다.
에러 내용을 관리하는 enum을 만든다.
리턴하고자 하는 값에 따라 httpStatus, message등은 다른 값으로 대체될 수 있다.
추후 에러 시에 어떤 에러가 발생했는지, 에러 내용은 어떤 것인지 알 수 있게 하기 위해 두 가지를 다루기로 했다.
@Getter
@AllArgsConstructor
public enum ErrorCode {
/* 100 CONTINUE : 정보성 상태 코드 */
TEST_ERROR(HttpStatus.CONTINUE, "ErrorCode를 통한 테스트 에러입니다."),
/* 400 BAD_REQUEST : 잘못된 요청 */
EMPTY_USER_ID(HttpStatus.BAD_REQUEST, "아이디를 입력해주세요."),
/* 500 BAD_GATEWAY : */
COMMON_ERROR(HttpStatus.BAD_GATEWAY, "오류가 발생했습니다.")
;
private final HttpStatus httpStatus;
private final String message;
}
400 에러 외에도 많은 에러가 있다.
에러 메시지는 아래의 url들을 참고하여 작성하였다.
1. https://velog.io/@hseoy/자주-사용하는-10가지-HTTP-Status-Code
2. https://developer.mozilla.org/ko/docs/Web/HTTP/Status
3. https://1-7171771.tistory.com/129
4. https://www.whatap.io/ko/blog/40/
에러가 발생했을 때에도 일반 응답과 거의 유사한 형태로 답변을 주고 싶었다.
(일반 응답은 나중에 정리할 것)
@Getter
public class ErrorResponse {
private ErrorResponseMeta meta;
public ErrorResponse(ErrorCode errorCode) {
this.meta = new ErrorResponseMeta(errorCode);
}
public ErrorResponse(int code, String message) {
this.meta = new ErrorResponseMeta(code, message);
}
}
Error Code로 에러를 보여주는 것 외에도, enum으로 관리하고 싶지 않은 에러가 있을 수 있다고 판단하여 에러코드와 에러 메시지명을 받을 수 있도록 하였다.
RuntimeException을 상속받는 CustomException을 작성한다.
@Getter
@AllArgsConstructor
public class CustomException extends RuntimeException {
private final ErrorCode errorCode;
private final int code;
private final String message;
public CustomException(ErrorCode errorCode) {
this.errorCode = errorCode;
this.code = 0;
this.message = "";
}
public CustomException(int code, String message) {
this.errorCode = null;
this.code = code;
this.message = message;
}
}
ErrorCode로 생성하는 방법과 code, message로 생성하는 방법이 있어서 생성자가 2개 필요하다.
그럼 이 CustomException으로 어떻게 인식할 건지?
컨트롤러에서 발생하는 Custom Exception을 잡아주는 @ExceptionHandler 어노테이션을 메서드에 사용한다. 에러 처리 이후 응답도 해야 하기 때문에 @RestControllerAdvice도 사용한다.
두 어노테이션에 대해서는 추가로 공부가 필요하다.
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(value = { CustomException.class })
protected ErrorResponse handleCustomException(CustomException e) {
if (!Optional.ofNullable(e.getErrorCode()).isEmpty()) {
return new ErrorResponse(e.getErrorCode());
} else {
return new ErrorResponse(e.getCode(), e.getMessage());
}
}
}
사용 예제는 아주 간단하다.
에러가 발생하면,
throw new CustomException(ErrorCode.EMPTY_USER_ID);
위와 같이 리턴해주면 된다.
그러면,
이런 형식으로 리턴이 된다.
포스트 끝~