1. 문제 상황
💡 excepiton이 발생할 때 response가 읽기 힘든 형태로 내려짐
- OS: MacOs
- 기타 정보 : Java 17, Spring Boot 2.7.9
1. exception 발생
@GetMapping("/exception")
public void throwException() {
throw new RuntimeException("테스트 에러 발생");
}
2. 에러 메세지가 아래와 같이 리턴됨

기본 에러 response가 한 눈에 보기 어려운 형태로 되어있어 exception handler를 정의할 필요성을 느끼게 되었습니다.
2. 해결 방법
@ControllerAdvice를 사용하여 에러를 처리
@ControllerAdvice란?
@ControllerAdvice는 Spring MVC에서 예외 처리를 담당하는 어노테이션입니다. 이 어노테이션을 사용하면 전역적으로 예외를 처리할 수 있는 클래스를 정의할 수 있습니다. 이 클래스에서는 @ExceptionHandler를 사용하여 특정 예외에 대한 처리 방법을 지정할 수 있습니다.
@ControllerAdvice를 사용한 exception handler 구현
1
Response dto 생성
@Getter
public class ExceptionResponse {
private final String message;
private final int status;
private final HttpStatus error;
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private final LocalDateTime timestamp;
public ExceptionResponse(String message, HttpStatus httpStatus) {
this.message = "[ERROR] " + message;
this.status = httpStatus.value();
this.error = httpStatus;
this.timestamp = LocalDateTime.now();
}
}
이번 예제에서 쓸 에러 메세지의 format은 위와 같습니다.
2
@ControllerAdvice로 Exception Handler 구현
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = {MethodArgumentNotValidException.class})
public ResponseEntity<Object> handleMethodArgumentNotValidException(
MethodArgumentNotValidException e) {
HttpStatus status = HttpStatus.BAD_REQUEST;
BindingResult bindingResult = e.getBindingResult();
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
List<String> errorMessages = new ArrayList<>();
for (FieldError fieldError : fieldErrors) {
String errorMessage = fieldError.getField() + ": " + fieldError.getDefaultMessage();
errorMessages.add(errorMessage);
}
ExceptionResponse response = new ExceptionResponse(errorMessages.toString(),
status);
return new ResponseEntity<>(response, status);
}
}
@ControllerAdvice를 붙인 클래스를 정의해주시면 됩니다.
위의 코드는 폼 유효성 검사나 DTO 객체의 유효성 검사를 통과하지 못했을 때 발생하는 에러를 핸들링하는 코드입니다.
번외
feign client로 받은 오류 처리
@ExceptionHandler(FeignException.class)
public ResponseEntity feignExceptionHandler(FeignException e) throws JsonProcessingException {
String responseJson = e.contentUTF8();
Map<String, String> responseMap = objectMapper.readValue(responseJson, Map.class);
return new ResponseEntity<>(responseMap, HttpStatus.valueOf(e.status()));
}
이렇게 하면 feign client로 받은 에러 response를 그대로 내려줄 수 있게 됩니다.
마치며
이번 글에서는 Spring 프로젝트에서 exception handler를 정의하고 에러메세지를 전역적으로 처리하는 방법에 대해 알아봤습니다.
'개발 일지' 카테고리의 다른 글
| API 게이트웨이 도입으로 MSA 기반 서비스 관리 향상 (0) | 2024.03.25 |
|---|---|
| Monolithic → MSA로 전환한 이야기 (0) | 2024.03.18 |
| docker compose로 실행한 프로그램 디버깅 하기 (0) | 2024.03.16 |