Spring 예외 처리 방법

Hye·2023년 1월 7일
0

📌 스프링의 기본 예외 처리 방법

  • Spring이 만들어질 때부터 에러 처리를 위한 BasicErrorController가 구현되어 있었음
  • 스프링 부트는 예외가 발생하면 기본적으로 /error로 에러 요청을 다시 전달하도록 WAS 설정을 해둠
  • 따라서, 별도의 설정이 없는 경우 예외 발생 시 BasicErrorController로 에러 처리 요청이 전달됨

📌 스프링이 제공하는 다양한 예외 처리 방법

  • Java에서는 예외 처리를 위해 try-catch를 사용해야 하지만, 모든 코드에 try-catch를 사용하는 것은 비효율적
  • Spring은 에러 처리 전략을 추상화한 HandlerExceptionResolver 인터페이스를 만듬
    • 대부분의 HandlerExceptionResolver는 발생한 Exception을 catch하고 HTTP 상태나 응답 메시지 등을 설정함
    • 따라서, WAS 입장에서는 해당 요청을 정상적인 응답으로 인식함
  • Spring에서는 아래와 같은 도구들로 ExceptionResolver를 동작시켜 에러를 처리할 수 있음
    • ResponseStatus
    • ResponseStatusException
    • ExceptionHandler
    • ControllerAdvice, RestControllerAdvice

1️⃣ @ResponseStatus

@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class CommentNotFoundException extends RuntimeExceiption {
 ...
}
  • 에러 HTTP 상태를 변경하도록 도와주는 어노테이션
  • 적용 가능한 경우
    • Exception 클래스 자체
    • 메서드에 @ExceptionHandler와 함께
    • 클래스에 @RestControllerAdvice와 함께
  • BasicErrorController에 의해 응답이 이루어짐
    • WAS까지 예외를 전달시킴
  • 👎 한계점
    • 에러 응답 내용을 수정할 수 없음
    • 예외 클래스와 강하게 결합되어 있기 때문에 같은 예외는 같은 상태와 에러 메시지를 반환함
    • 별도의 응답 상태가 필요한 경우 예외 클래스를 추가해야 함
    • WAS까지 예외가 전달되고 WAS의 에러 요청 전달이 진행됨
    • 외부에서 정의한 Exception 클래스에는 @ResponseStatus를 붙일 수 없음

2️⃣ ResponseStatusException

  • @ResponseStatus의 프로그래밍적 대안으로 추가됨

  • HttpStatus와 함께 선택적으로 reason, cause 추가 가능

  • 언체크 예외를 상속받기 때문에 명시적으로 에러를 처리하지 않아도 됨

  • 👍 장점

    • 기본적인 예외 처리를 빠르게 적용 가능
    • HttpStatus를 직접 설정해 예외 클래스와의 결합도를 낮출 수 있음
    • 불필요하게 많은 예외 클래스를 만들지 않아도 됨
    • 프로그래밍 방식으로 예외를 직접 설정해 예외를 더 잘 제어할 수 있음
  • 👎 한계점

    • 프로그래밍 방식으로 예외를 직접 처리해 일관된 예외 처리가 어려움
    • 예외 처리 코드가 중복될 수 있음
    • Spring 내부의 예외 처리가 어려움
    • 예외가 WAS까지 전달되고, WAS의 에러 요청 전달이 진행됨

3️⃣ ExceptionHandler

  • 매우 유연하게 에러를 처리할 수 있는 방법을 제공
  • 어노테이션을 추가할 수 있는 경우
    • 컨트롤러의 메소드
    • @ControllerAdviceRestControllerAdvice가 있는 클래스의 메소드
  • Exception 클래스들을 속성으로 받아 처리할 예외를 지정할 수 있음
  • 예외 클래스를 지정하지 않는 경우 파라미터에 설정된 예외 클래스를 처리
  • @ResponseStatus와 결합 가능
    • 둘 다 Status를 지정하는 경우 Response Entity가 우선 순위를 가짐
  • @ResponseStatus와 달리 응답을 자유롭게 다룰 수 있음
    • code : 어떤 종류의 에러가 발생했는지에 대한 에러 코드 (가독성 좋은 값을 사용)
    • message : 왜 에러가 발생했는지에 대한 설명
    • errors : 어떤 값이 잘못되어 @Valid에 의한 검증이 실패한 것인지를 위한 에러 목록

4️⃣ ControllerAdvice, RestControllerAdvice

  • 가장 좋은 방법
  • 차이점 : @ResponseBody
    • 응답을 JSON으로 내려줌
  • 여러 컨트롤러에 대해 전역적으로 ExceptionalHandler를 적용해줌
  • 👍 장점
    • 하나의 클래스로 모든 컨트롤러에 대해 전역적으로 예외 처리가 가능함
    • 직접 정의한 에러 응답을 일관성있게 클라이언트에게 내려줄 수 있음
    • 별도의 try-catch문이 없어 코드의 가독성이 높아짐
  • ❗️ 사용시 주의할 점
    • 한 프로젝트당 하나의 ControllerAdvice만 관리
    • 여러 ControllerAdvice가 필요하다면 basePackages나 annotations 등을 지정해야 함
    • 직접 구현한 Exception 클래스들은 한 공간에서 관리
profile
공부중 📚

0개의 댓글

관련 채용 정보