Custom Exception 다루기

seul·2022년 8월 8일
0

공부

목록 보기
1/13
post-thumbnail

What I learned while coding

말 그대로, 내가 코딩을 하면서 배운 것 💻
내가 일을 하든, 사이드 프로젝트를 하든, 배운 모든 것들을 적어볼 생각이다 (미래의 내가 다시 보기 위해)

📌 Custom Exception

API 호출 시에는 일관된 응답을 보내주어야 한다.
그것은 로직이 정상적으로 진행되었든, 오류가 발생했든 동일해야 할 것이다.
그래서 응답을 표준화 하게 되는데.....

이번 시간에는 로직 처리 중 오류 시 리턴되는 오류 형식을 표준화 하고 내가 원하는 오류 메시지를 리턴할 수 있게끔 처리하는 방법에 대해 정리해보겠다.

📎 Error Code

에러 내용을 관리하는 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/

📎 Error Response

에러가 발생했을 때에도 일반 응답과 거의 유사한 형태로 답변을 주고 싶었다.
(일반 응답은 나중에 정리할 것)

@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);
    }
}

ErrorResponseMeta

  • code: HttpStatus의 code
  • error: 에러코드명
  • message: 에러 시 에러 내용을 간단한 줄글로 표현할 때의 메시지
  • path, dateTime: 생략 가능

생성자가 두 개로 나뉜 이유

Error Code로 에러를 보여주는 것 외에도, enum으로 관리하고 싶지 않은 에러가 있을 수 있다고 판단하여 에러코드와 에러 메시지명을 받을 수 있도록 하였다.

📎 Custom Exception

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으로 어떻게 인식할 건지?

📎 Global Exception Handler

컨트롤러에서 발생하는 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);

위와 같이 리턴해주면 된다.
그러면,

이런 형식으로 리턴이 된다.

포스트 끝~

profile
자존감은 일상의 성실함으로부터 온다

0개의 댓글