본문 바로가기

프로젝트/라꾸라꾸 프로젝트

[예외처리] 방법 소개와 프로젝트 적용

스프링에서 예외 처리하는 3가지 방법

1) try - catch : “각 메소드” 안에서 처리

2) 어노테이션@ExceptionHandler :  “컨트롤러 자체”에서 처리, Global level에서 처리 → 추천

3) 클라이언트에서 전달되기 직전에 처리

실행흐름

[컨트롤러에서 예외 발생]

  1. 에러가 터지면
  2. Dispatcher Servlet을 통해 ExceptionResolver 에게 간다.
  3. ExceptionHandlerExceptionResolver에게 간다.
  4. 이것이 컨트롤러에게 가서 “@ExceptionHandler”부분을 찾는다.
  5. 해당 메소드를 실행시킨다.

-자세하게 설명하자면!

컨트롤러를 호출한 결과 IllegalArgumentException 예외가 컨트롤러 밖으로 던져진다.

예외가 발생했으로 ExceptionResolver 가 작동한다. 가장 우선순위가 높은 ExceptionHandlerExceptionResolver 가 실행된다. ExceptionHandlerExceptionResolver 는 해당 컨트롤러에 IllegalArgumentException 을 처리할 수 있는 @ExceptionHandler 가 있는지 확인한다. illegalExHandle() 를 실행한다. @RestController 이므로 illegalExHandle() 에도 @ResponseBody 가 적용된다. 따라서 HTTP 컨버터가 사용되고, 응답이 다음과 같은 JSON으로 반환된다. @ResponseStatus(HttpStatus.BAD_REQUEST) 를 지정했으므로 HTTP 상태 코드 400으로 응답한다.

 

 

본 프로젝트에서는 Global한 부분에 "Error Code", "Error Response", "Global ExceptionHandler" 3개의 폴더를 만들고 각 엔티티 별로 exception 폴더를 만들어서 에러 부분을 처리했다. ("각 엔티티 별"이라는 것은 예를 들어, UserNotFoundException이라면 User 엔티티 exception 폴더 안에 UserNotFoundException 클래스를 만들고 ResourceNotFound를 상속 받는다. )

Error Code는 enum으로 에러 메시지들을 일관성있게 관리하는 것이다. Error Response는 예외 응답을 통일성있게 하기 위해 형식을 정의한 것이다. 본 프로젝트에서는 status, code, message, date로 표현했다. Global ExceptionHandle은 각 예외의 클래스들을 대상으로 @ExceptionHandler를 붙여 메소드를 실행하는 부분이다.