99클럽 2일차 TIL: Spring Boot 에러 핸들링
2024. 4. 5. 17:56ㆍSpring Boot
728x90
반응형
#1. 오늘의 학습 키워드
자바스프링부트에서 커스텀 된 에러 메시지를 controller 로 보내고 싶을 때 방법
- api 호출 → controller → service로 이어질 때, 일반적인 exception 이 아닌, 사용자 request 의 논리적 오류를 핸들하고 싶을 때:
- 이런 상황에서의 Exception은 RuntimeException 을 상속한 커스텀 Exception 클래스인 ApiException으로 던져진다.
- 실질적인 오류가 아닌 논리 오류로 validation fail에 해당하기 때문에 이렇게 처리를 하였다.
- 프론트엔드 단과 합의된 반환 코드(사용자의 입력값 오류 (클라이언트 error 4xx))와, 커스텀된 메시지로 오류를 throw 한다.
- 이런 상황에서의 Exception은 RuntimeException 을 상속한 커스텀 Exception 클래스인 ApiException으로 던져진다.
public int method(Boolean isError) {
try {
if (isError) {
throw new ApiException(MessageCode.USER_ERROR_CODE,"커스텀에러 메시지");
}
return 1;
} catch (ApiException e) {
throw e;
} catch (Exception e) {
throw new ApiException(MessageCode.ERROR_CODE, e.getLocalizedMessage());
}
}
#2. 공부한 내용
- @ExceptionHandler
- 위 예시 service 메서드에서의 catch 블록에서 아래와 같이 로깅을 남겨도 되지만,
public int method(Boolean isError) {
try {
if (isError) {
throw new ApiException(MessageCode.USER_ERROR_CODE,"커스텀에러 메시지");
}
return 1;
} catch (ApiException e) {
log.warn("Exception : {}", e.getStackTrace()[0]);
throw e;
} catch (Exception e) {
log.error("Exception : {}", e.getStackTrace()[0]);
throw new ApiException(MessageCode.ERROR_CODE, e.getLocalizedMessage());
}
}
- ExceptionHandler 어노테이션으로 구현한 에러 핸들링을 처리하는 메서드를 통해 ApiException 이 던져졌을 때 코드 범위를 통해서 로그 warn이나 error를 찍는 방법이 있다
@ExceptionHandler({ApiException.class})
public <T extends ApiException> ResponseEntity<JsonResponse> handleApiException(T exception,
HttpServletRequest request) {
if (exception.getJsonResponse().getCode() == MessageCode.USER_ERROR_CODE) {
log.warn("<<ErrorCode {}>> Program Exception : {}",
exception.getJsonResponse().getCode(),
exception.getJsonResponse().getMessage());
} else {
log.error("<<ErrorCode {}>> Program Error : {} : {}",
exception.getJsonResponse().getCode(),
exception.getJsonResponse().getMessage(),
exception.getLocalizedMessage());
}
//...
}
- @RestControllerAdvice
- 해당 메서드에서 뿐만 아니라, 다른 메서드에서도 동일한 이유 ( 사용자 입력값의 논리적 오류 ) 로 에러를 던질 수 있어야 하고, 해당 에러들에 대한 동일한 처리가 이뤄질 수 있어야 한다.
- 위 @ExceptionHandler 어노테이션은 전역적으로 지원이 되고, 해당 어노테이션은 해당 @RestControllerAdvice 어노테이션이 지원을 한다.
- 원래 @ExceptionHandler 어노테이션은 controller 단위로 에러 핸들링을 지원하였다고 한다. 즉 controller 마다 따로 핸들링을 해주거나, 에러 핸들링을 설정한 base controller를 다른 controller가 상속하여 사용해야 돼서, 번거롭다.
- 이는 status code나 response body에 대한 제어를 허용하고, 여러개의 다른 exception class의 에러 핸들링을 같은 메서드에서 할 수 있게끔 허용한다.
@ExceptionHandler({ApiException1.class, ApiException2.class})
#3. 오늘의 회고
- 에러 핸들링이나 로깅 같은 부분은 API 구현 과정에서 처음에는 중요하지 않아 보일 수 있다. 그러나 구현된 API들이 배포가 되면, 프론트 개발 과정에서 호출을 하면서 에러는 필히 발생되게 되고, 이때 비로소 중요해진다.
- 의도된 에러 핸들링과 의도되지 않은 에러 핸들링을 구분할 필요가 있으며, 프론트엔드 단 개발 시 해당 에러 핸들링된 메시지를 어떻게 사용자에게 보여줄 지 결정할 때 중요한 지표가 되기도 한다.
- 또한 로깅 툴을 통해 ( grafana / prometheus) 에러 로그를 직관적으로 볼 수 있으며, 화면에서는 보이지 않지만 발생되는 실질적 에러들에 대해서 보수를 할 수 있게끔 도와준다.
728x90
반응형
'Spring Boot' 카테고리의 다른 글
Spring Boot: mongoDB → PostgreSQL 마이그레이션: Conversing 이슈 해결 (0) | 2024.09.24 |
---|---|
99클럽 8일차 TIL: SpringBoot - Profile (0) | 2024.04.11 |
Java Spring - 공부 여정 (0) | 2024.03.16 |
스웨거(Swagger) - @ExampleObject value 속 긴 String 분리 과정 정리 (1) | 2024.03.15 |
스웨거(Swagger) - 어노테이션 간단 정리 (0) | 2024.03.14 |