스터디/Spring

Spring에서 Execption을 핸들링하는 방법

Big Sun 2024. 1. 15. 21:07
728x90

 

서비스를 만들면서 예외 처리는 정말 중요합니다. 이번 포스팅에서는 Spring Boot에서 예외를 어떻게 핸들링할 수 있지에 대해서 알아보겠습니다.

예외를 처리하는 방법은 @ExceptionHandler 사용, HandlerExceptionResolver를 사용,  @ControllerAdvice 사용 이렇게 3가지가 있습니다.


Controller - level : @ExceptionHandler

 

Spring Boot에서 예외를 처리하는 방법 중 하나는 Controller의 메서드 위에 바로 @ExceptionHandler를 사용하는 것입니다.

public class FooController{
    
    //...
    @ExceptionHandler({ CustomException1.class, CustomException2.class })
    public void findFoo() {
        //
    }
}

 

 

그러나 이 방법을 사용하게 되면, Controller의 메서드마다 @ExceptionHandler를 다 작성을 해야합니다. 또한, 같은 예외임에도 불구하고 각 메서드에 다시 작성해줘야합니다. 때문에 이 방법은 사용하지 않습니다.

 

HandlerExceptionResolver 사용

 

HandlerExceptionResolver를 사용하면, 컨트롤러 레벨에서 발생하는 모든 예외를 핸들링할 수 있습니다.

 

 

해당 인터페이스를 구현한 AbstractHandlerExceptionResolver 클래스의 resolveException 메서드를 살펴보면, resolveException 메서드 내에서 doResolveException 메서드를 호출해 예외를 핸들링하는 모습을 볼 수 있습니다.

 

DefaultHandlerExceptionResolver의 doResolveException메서드입니다. 이 메서드에서는 스프링에서 정한 몇몇 예외들을 핸들링하고 있습니다. (이름이 DefaultHandlerExceptionResolver 라는 것에서 눈치를 챌 수도 있을 거 같습니다.)

 

handleHttpRequestMethodNotSupported 메서드를 확인해보겠습니다. 해당 메서드에서는 Header를 세팅하고, 상태 코드를 반화하고 있습니다. 그리고, 빈 ModelAndView 객체를 반환하고 있습니다. 
중요한 것은 예외 메시지는 반환하고 있지 않는 사실입니다.

 

또한, 한 가지 불편한 것은 ResponseEntity를 사용하지 않고 ModelAndView 객체를 사용하는 것입니다.

물론, 아래의 예시처럼 ModelAndView 객체를 사용해 예외 메시지를 전달할 수도 있습니다. 그러나 불편합니다.

 

 

다행히 스프링 부트에서는 편하게 예외를 핸들링할 수 있도록 @RestControllerAdvice 를 지원해줍니다.

 

@RestControllerAdvice

@RestControllerAdvice와 @ExceptionHandler를 같이 사용하면 ExceptionHandlerExceptionResolver가 처리할 수 있는 예외를 찾아서 예외를 처리해줍니다. 

 

 

이 방법은 HandlerExcepionResolver를 사용하는 방식과 비교하였을 때 중앙에서 한 번에 관리할 수 있어 유지보수하기 편합니다.


결론은 @RestControllerAdvice와 @ExceptionHandler를 사용해서 예외를 핸들링하자! 입니다.

 

728x90