예외 처리
자바에서 try-catch
를 활용하여 예외를 잡던 것 처럼 스프링에서도 throw
로 예외를 던진 것을 @ExceptionHandler
를 통해 잡을 수 있다.
@ExceptionHandler
를 활용하면 애플리케이션에서 예외가 발생했을 때 예외를 잡아 원인을 응답 메세지로 받아볼 수 있다.
@ExceptionHandler
public ResponseEntity handleException(MethodArgumentNotValidException e) {
final List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
return new ResponseEntity<>(fieldErrors, HttpStatus.BAD_REQUEST);
}
예외가 발생했을 때 응답 메세지는 다음과 같은데, 기본적으로 지원하는 fieldErrors
는 원하지 않는 정보까지 전달해줄 수도 있다.
[
{
"codes": [
"Email.memberPostDto.email",
"Email.email",
"Email.java.lang.String",
"Email"
],
"arguments": [
{
"codes": [
"memberPostDto.email",
"email"
],
"arguments": null,
"defaultMessage": "email",
"code": "email"
},
[],
{
"arguments": null,
"defaultMessage": ".*",
"codes": [
".*"
]
}
],
"defaultMessage": "올바른 형식의 이메일 주소여야 합니다",
"objectName": "memberPostDto",
"field": "email",
"rejectedValue": "hgd@",
"bindingFailure": false,
"code": "Email"
}
]
원하는 정보만 전달하는 방법
원하는 정보만을 전달하기 위해서는 원하는 예외 정보만을 담는 클래스가 필요하다. 특정 클래스를 생성하여 필요한 정보만을 담을 수 있다.
@Getter
@AllArgsConstructor
public class ErrorResponse {
private List<FieldError> fieldErrors;
@Getter
@AllArgsConstructor
public static class FieldError {
private String field;
private Object rejectedValue;
private String reason;
}
}
이를 기반으로 핸들러 메서드의 예외 메세지를 반환받으면 다음과 같은 결과를 얻을 수 있다. 이름과 이메일이 유효성 검증에 실패해 오류 메세지로 반환 되었다.
AOP를 활용한 예외 처리
Controller에서 예외를 잡으면 모든 Controller에 예외 처리 핸들러 메서드가 필요하게 된다. Controller가 늘어나면 작성해야할 @ExceptionHandler
또한 늘어난다.
이러한 문제를 해결하기 위해서는 @RestControllerAdvice
를 활용하여 예외 처리를 공통화하면 각각의 Controller에 예외 처리 핸들러 메서드를 추가하지 않고 공통적으로 사용할 수 있다.
@RestControllerAdvice
public class GlobalExceptionAdvice{
}
비즈니스적인 예외 던지기와 예외 처리
애플리케이션의 예외는 두 가지로 나눌 수 있다.
예외를 잡아 해당 예외를 복구하거나 회피하는 어떤 구체적인 처리를 해야하는 예외를 말한다. 대표적으로 ClassNotFoundException
가 있다.
예외를 잡아 해당 예외에 대한 처리를 할 필요가 없는 예외를 의미하며 명시적으로 잡아서 처리할 필요가 없다. 대표적으로 NullPointerException
, ArrayIndexOutOfBoundsException
등이 있다.
RuntimeException
을 상속하는 예외는 모두 언체크 예외이며 RuntimException
을 상속하여 개발자가 직접 사용자 정의 예외를 구현할 수 있다.
백엔드 서버와 외부 시스템과의 연동에서 발생하는 에러 처리
시스템 내부에서 조회하려는 리소스가 없는 경우
이외에도 여러 상황에서 예외를 던져야하는 상황이 발생한다. 예외도 상황이 다양하게 존재하기 때문에 구체적으로 어떤 예외가 발생하였는지에 대한 예외 처리가 필요하다.