이번 글에서는 예외처리를 수행하는 예시에 대해서 적어보려한다.
커스텀 예외 생성 및 핸들러 등록
먼저, 기본적으로 재사용이 가능하도록 RuntimeException을 상속받는 어플리케이션 Exception을 생성한다.
@Getter
@ToString
@RequiredArgsConstructor
public class PeachPickerException extends RuntimeException {
private final ErrorProperty errorProperty;
private String message;
public PeachPickerException(String message, ErrorProperty errorProperty) {
this.message = message;
this.errorProperty = errorProperty;
}
}
public interface ErrorProperty {
HttpStatus getStatus();
String getMessage();
}
해당 Exception은 에러 메세지와, 에러 상태를 표현하는 ErrorPropery를 가지는 Exception 클래스이다.
@Getter
@RequiredArgsConstructor
public enum DrawingErrorProperty implements ErrorProperty {
DRAWING_AT_ERROR(HttpStatus.BAD_REQUEST, "추첨 시각이 올바르지 않습니다"),
;
private final HttpStatus status;
private final String message;
}
public class DrawingAtErrorException extends PeachPickerException {
public final static DrawingAtErrorException EXCEPTION = new DrawingAtErrorException();
private DrawingAtErrorException() {
super(DrawingErrorProperty.DRAWING_AT_ERROR);
}
}
그리고 상황별로 해당 공통 Exception을 상속받는 개별 Exception class 를 생성해서 사용하도록 구현하였다.
@RestControllerAdvice
@Slf4j
public class PeachPickerExceptionHandler {
@ExceptionHandler(PeachPickerException.class)
public ResponseEntity<Object> handleCustomException(PeachPickerException e) {
e.printStackTrace();
log.error("Peach Picker Exception : " + e.getErrorProperty().getMessage());
return handleExceptionInternal(e.getErrorProperty());
}
private ResponseEntity<Object> handleExceptionInternal(ErrorProperty errorProperty) {
return ResponseEntity.status(errorProperty.getStatus())
.body(makeErrorResponse(errorProperty));
}
}
@Getter
@Builder
@AllArgsConstructor
public class ErrorResponse {
private HttpStatus status;
private String message;
public ErrorResponse(ErrorProperty errorProperty) {
this.status = errorProperty.getStatus();
this.message = errorProperty.getMessage();
}
}
마지막으로, Exception Handler를 작성하여 등록한 것이다. 어플리케이션에서 사용하는 PeachPickerException 이 발생한 경우, 로그를 찍고 응답형태를 생성하여 클라이언트로 응답하게 된다.
해당 설정 후, 서비수 수행시 DrawingAtErrorException 이 발생했을 때 클라이언트에 가는 응답은 아래와 같다.
{
"status": 400,
"message": "추첨 시각이 올바르지 않습니다"
}
1편에서 작성한 내용과 다르게, 불필요한 부분은 많이 줄였고 클라이언트에서 사용자에게 표시할 수 있을 에러 메세지를 담도록하여 사용성을 높였다.
결론
이렇게, 사용자 정의 예외를 생성해서 응답하는 예제를 간단하게 보았다.
처음에 해당 방식을 접했을 때는, 예외를 체계적으로 정의하고 관리할 수 있어 혁신적인 방법이다! 라고 생각하며 모든 프로젝트에 도입하기 시작하였다.
그렇게 하나, 둘씩 적용하다보니 해당 방식에 큰 단점이 생기게 되었다.
먼저, 코드의 양이 기하급수적으로 늘어나기 시작했다. 모든 상황별로 Property Enum 1개와 Class 1개가 꼭 필요하고 이는 개발자의 오버헤드가 점점 커진다는 단점이 생겼다.
또한, 설정을 위해 모든 프로젝트에 같은 내용을 반복해서 작성한다는 것이다.
이렇게 몇번씩 노가다를 하다보니, 좀더 간단하게 Handler를 등록하고 예외를 관리할 수 있는 커스텀 라이브러리를 제작해서 오버헤드를 낮춰보자! 라는 생각을 가지게 되었고, 다음편에서 해당 내용에 대하여 설명해보고자 한다.
'Web > Spring Boot 예외 처리' 카테고리의 다른 글
[Spring Boot] 예외 처리 라이브러리 만들기 (3) (0) | 2024.08.13 |
---|---|
[Spring Boot] 예외 처리 라이브러리 만들기 (1) (0) | 2024.08.13 |