백엔드

[백엔드] Blog - 전역 예외 커스텀 처리하기 @RestControllerAdvice, @ExceptionHandler

Campus Coder 2024. 9. 24. 01:24
728x90
반응형

목차

  • 1. ExceptionAdvice
    • 1.1. handleGlobalException 메서드
    • 1.2. handleMethodArgumentNotValid 메서드

 

1. ExceptionAdvice (전역 예외처리 핸들러)

최근에 개발한 블로그 프로젝트에서 사용한 커스텀 전역 예외처리 핸들러이다.

 

 

@Slf4j

Lombok의 어노테이션으로, 클래스에 로깅 기능을 추가한다. 이 어노테이션을 사용하면 log 객체를 생성하지 않고도 로깅할 수 있다.

ResponseEntityExceptionHandler 내부에도 logger가 정의되어 있기는 하나 이 어노테이션이 사용하기 편리하다.

 

log.error() 출력문 예시

 

@RestControllerAdvice(annotations = {RestController.class})

전역적으로 @RestController에서 발생한 예외를 이곳에서 처리하는 데 사용된다.

이 클래스는 전역 예외 처리를 담당하는 @ControllerAdvice의 변형이다.

 

ResponseEntityExceptionHandler

주로 HTTP 요청을 처리하는 동안 발생할 수 있는 다양한 예외를 자동으로 처리하며, 적절한 HTTP 상태 코드와 응답을 반환한다. Spring MVC와 관련된 여러 예외들을 다루기 위한 메서드들이 정의되어 있다. 이 메서드들을 오버라이드하여 커스텀 예외 처리 로직을 구현할 수 있다.

 

 

1.1. handleGlobalException 메서드

 

@ExceptionHandler(value = {GlobalException.class})

GlobalException이라는 커스텀 예외가 발생할 때 호출되는 메서드이다.

다음과 같은 상황에서 발생한다

 

GlobalException e, HttpServletRequest request (인자)

예외와 요청 객체를 인자로 받는다.

 

GlobalException과 GlobalErrorCode는 예외처리를 위해 직접 정의한 코드이다. 아래에서 자세하게 설명하겠다.

GlobalException은 GlobalErrorCode를 래핑하고 있는 클래스이다.

 

HttpServletRequest는 클라이언트의 요청에 대한 정보가 담겨있는 객체이다. 자세한 내용은 다음을 참고하자.

https://velog.io/@oliviarla/HttpServletRequest-HttpServletResponse-%EA%B0%9D%EC%B2%B4%EB%9E%80

 

 

new ErrorResponse(e.getGlobalErrorCode(), request.getRequestURI())

예외에 해당하는 에러 응답 객체를 생성한다. 생성자를 정의해 ErrorResponse의 필드가 적절히 초기화되도록 한다.

 

 

return new ResponseEntity<>()

에러 응답과 함께 해당 HTTP 상태 코드를 반환한다. 이 반환은 최종적으로 클라이언트가 받는 응답이 된다.

 

 

예시

 

예를 들어 Service에서 회원 가입 로직 도중 중복 유저가 있어서 예외를 던졌다고 가정해 보자.

 

 

이 예외는 해당 서비스를 호출한 컨트롤러로 던져진다. 컨트롤러에서는 예외를 별도로 처리하지 않고, 예외가 발생한 그대로 전파되도록 둔다.

 

 

컨트롤러에서 발생한 예외가 글로벌 예외 처리 핸들러 ExceptionAdvice로 넘어가게 된다. 여기서 handleGlobalException 메서드가 호출되면서 GlobalException을 처리한다.

 

ExceptionAdvice의 handleGlobalException 메서드에서는 GlobalException을 받아 커스터마이징 된 에러 응답인 ErrorResponse를 생성하고, 클라이언트에게 반환한다.

 

최종 클라이언트 응답

 

 

1.2. handleMethodArgumentNotValid 메서드

 

handleMethodArgumentNotValid 메서드는 DTO 유효성 검사를 위한 예외 처리 메서드이다. 이 메서드는 스프링에서 @Valid 또는 @Validated 어노테이션을 사용하여 DTO의 필드에 대한 유효성 검사가 실패했을 때 발생하는 MethodArgumentNotValidException을 처리한다.

 

 

DTO 클래스에서 정의한 유효성 검사 어노테이션(예: @NotBlank, @Size, @Email 등)이 적용된 필드에 잘못된 값이 전달될 경우 해당 예외가 발생하며, handleMethodArgumentNotValid 이를 처리하게 된다.

 

 

@Valid 또는 @Validated 어노테이션

  • 컨트롤러 메서드에서 DTO 객체를 파라미터로 받을 때 @Valid 또는 @Validated 어노테이션을 붙이면 스프링이 해당 DTO 객체의 필드 값이 유효한지 자동으로 검증한다.
  • 예를 들어, 필드에 @NotBlank 같은 어노테이션이 붙어 있고 빈 값이 전달되면 유효성 검사가 실패한다.

 

커스터마이징 handleMethodArgumentNotValid 메서드

ResponseEntityExceptionHandler의 handleMethodArgumentNotValid 메서드를 오버라이딩했다.

  • 이 메서드는 MethodArgumentNotValidException을 처리한다.
  • DTO의 필드 중 어떤 필드가 유효성 검사를 통과하지 못했는지에 대한 에러 메시지와 함께 HTTP 400(BAD REQUEST) 상태 코드를 반환한다.
  • 메서드 내에서 getFieldErrors() 메서드를 사용하여 어떤 필드가 유효성 검사를 통과하지 못했는지 확인하고, 첫 번째 에러 메시지를 추출한다.
  • 지정한 예외 클래스 ErrorResponse의 형식에 맞춰 클라이언트에게 응답한다.

 

728x90
반응형