먼저 Exception Handler를 정의하기 전에 Handler에서 관리할 예외들을 만들었다.
다양한 예외들을 만들기 위해서 인터페이스를 구현하여 만들었다.
+ RuntimeException을 상속받았는데 모든 Exception의 최상위 클래스는 Throwable로 존재한다.
public interface ApiExceptionIfs {
ErrorCodeIfs getErrorCodeIfs();
String getErrorDescription();
}
@Getter
public class ApiException extends RuntimeException implements ApiExceptionIfs {
private final ErrorCodeIfs errorCodeIfs;
private final String errorDescription;
public ApiException(ErrorCodeIfs errorCodeIfs) {
super(errorCodeIfs.getDescription());
this.errorCodeIfs = errorCodeIfs;
this.errorDescription = errorCodeIfs.getDescription();
}
public ApiException(ErrorCodeIfs errorCodeIfs, String errorDescription) {
super(errorDescription);
this.errorCodeIfs = errorCodeIfs;
this.errorDescription = errorDescription;
}
public ApiException(ErrorCodeIfs errorCodeIfs, Throwable tx) {
super(tx);
this.errorCodeIfs = errorCodeIfs;
this.errorDescription = errorCodeIfs.getDescription();
}
public ApiException(ErrorCodeIfs errorCodeIfs, Throwable tx, String errorDescription) {
super(tx);
this.errorCodeIfs = errorCodeIfs;
this.errorDescription = errorDescription;
}
}
이제 Exception들을 관리할 Handler를 작성해보겠다.
@RestControllerAdvice 공통 관심사 관련 로직 처리
@ExceptionHandler 어떤 예외에 대해서 처리를 할지 설정
이 두 어노테이션을 통해 예외 처리를 한다.
+여기서 ApiException은 스프링에서 주입해준다.
@Slf4j
@RestControllerAdvice
@Order(value=Integer.MIN_VALUE) // 최우선 처리
public class ApiExceptionHandler {
@ExceptionHandler(ApiException.class) // ApiException에 해당하는 예외처리 실행
public ResponseEntity<Api<Object>> apiException(
ApiException apiException
) {
log.error("", apiException); //ApiException은 RunTimeException을 상속받았기 때문에 stacktrace 가능
var errorCode=apiException.getErrorCodeIfs();
return ResponseEntity
.status(errorCode.getHttpStatusCode())
.body(
Api.ERROR(errorCode, apiException.getErrorDescription())
);
}
}
Exception Handler를 통해
1. 코드를 가독성 좋게 나누고 ( api와 오류 처리(응답) 코드 분리)
2. 스택 트레이스를 통해 로직 수집 (클라이언트에 자세한 오류 내역을 숨길 수 있음)
->컨트롤러에서 응답을 주나 Exception Handler를 통해서 응답을 주나 클라이언트 입장에서는 같음
따라서 Api 응답은 성공 or 실패만 주면된다.
'Springboot' 카테고리의 다른 글
[스프링 부트] JWT 검증 및 사용자 정보 가져오기 (0) | 2024.07.15 |
---|---|
[스프링 부트] Interceptor를 통한 인증 (0) | 2024.07.10 |
[스프링 부트] Api 공통 spec (0) | 2024.07.10 |
[스프링 부트] 커스텀 Object Mapper (0) | 2024.07.09 |
[스프링 부트] 멀티 모듈 Bean 등록 (0) | 2024.07.08 |