← Back to Home

SpringBoot 예외처리하기 - Exception Handling

SpringBoot Exception 처리

웹에서 에러가 발생했을 경우에는 크게 세가지 정도로 작업이 될 수 있다.

  • 에러페이지
  • HTTP Status 4XX 에러, 5XX 에러
  • HTTP 200 + Error Message

Exception을 처리하는 것은 이미 SpringBoot에 준비가되어있다.

관련된 어노테션을 확인 해 보고 어떻게 적용을 할 것인지 살펴보자

@ControllerAdvice / @RestControllerAdvice

페이지를 보여주는 기능을 처리하는 View Resolver에 사용 할 수 있다. 즉, WhiteLabel Page라던지 에러가 났을 경우 보여주는 화면에 대한 처리에 적용 할 수 있는 어노테이션이다

@ExceptionHandler

특정 Controller에 적용시키면, 모든 에러가 그쪽으로 Catch될 수 있는 처리를 해 주는 기능이다

위의 @Advice와 @ExceptionHandler를 사용해서 Exception을 처리 해 보도록 하자

Exception Flow

Exception 처리 준비하기

Controller, Dto 준비하기

Exception 처리를 위해 Exception이 일어날만한 Controller를 생성 해 보자

Exception이 일어날 Controller

위의 컨트롤러는 User Dto를 사용하고있다. User Dto는 아래와 같이 만들었다

exception_userdto.png

준비가 완료되었으니, Exception이 일어날 만 한 경우를 생각 해 보고 Exception들을 처리 해 줄 패키지를 만들어보자

GET Mapping이 되어있는 주소에는 requestParam으로 name, password, email, phone, age 를 받아주고 있다. 각각 required 옵션이 false로 되어있기 때문에 데이터를 보내지 않아도 큰 무리가 없겠지만, 맨 밑에 있는 int my_number = 100 + age; 라는 코드는 age가 Null이라면 Exception이 날 수 있다. 이런 상황을 가정하고, Exception Handler를 작성 해 보고자 한다.

Exception Class 만들기 - @Advice 사용하기

@Advice 어노테이션이 붙은 클래스는, Exception이 나는 모든경우에 거쳐간다. 그래서 나는 Exception들을 다루기 위해 따로 클래스로 빼두었고, 나중에는 각각 프로젝트 도메인별로 적용하면 될 것 같다.

exception_rest_advice.png

  • REST API에 맞게, @RestControllerAdvice 를 사용했고, @ExceptionHandler 를 적용하여 Exception을 받을 객체라는것을 명시했다
  • 함수 인자로 Exception을 받아 해당하는 Exception 처리를 다룰 수 있도록 했다.

위의 코드는 모든 Excpetion에 대해 처리 해 줄 수 있는 Exception.class 를 값으로 가지고있다. 관련된 Exception인지 출력 해 보려면 e.getClass().getName() 을 출력해보면 현재의 Exception이 어떤 Exception인지 알 수 있어서 해당하는 내역에 따라 따로 처리 해 줄 수 있다.

현재 RequestParam과 관련되어서 Method Argument와 관련된 에러이므로 해당하는 에러를 따로 처리 해 보도록 하자

Exception Class 만들기 - Argument Exception

@ExceptionHandler(value = Exception.class) 를 좀 더 세분화해서 만들어 보려고 한다.

위에서 말했듯이, Method Argument와 관련된 기능들을 사용 할 것 이기 때문에 맞는 기능을 찾아 적용 해 주자

exception_method_exception.png

Exception 함수의 인자가 Exception.class 에서, MethodArgumentNotValidException.class 으로 바뀌었다.

모든 Exception 이름을 외울 수는 없지만, 위에서 출력한 e.getClass().getName() 으로 해당하는 Exception의 이름을 알 수 있고, 공통으로 처리해도 되고 방금처럼 따로 만들어서 처리해도 된다.