[Spring MVC] 예외 처리

·2022년 10월 30일
0

Spring

목록 보기
14/24
post-thumbnail

예외 처리

유효성 검증에 실패한 경우, 이 실패를 하나의 예외로 간주하고 예외를 던져(Throw) 예외 처리를 유도한다.

  • 예외 처리 후, Response Body는 Json형식의 배열이 담기게 된다.
    • 배열인 이유? 유효성 검증에 실패하는 멤버 변수가 하나 이상일 수 있기 때문

Controller레벨에서의 예외 처리

1. @ExceptionHandler 애너테이션의 사용

: 메서드 레벨에 추가한다.

  • Controller 클래스 내부에 @ExceptionHandler을 추가한 예외 처리 핸들러 메서드를 생성한다.
  • 에러 정보를 기반으로 한 ErrorResponse 클래스를 만들어 필요한 정보만 담은 후, 클라이언트 쪽으로 전달한다.

💡 @ExceptionHandler의 단점
1. Controller 클래스에 위치하기 때문에 각 Controller 클래스마다 작성해 코드의 중복이 발생한다.
2. Controller 클래스에 에러 처리 핸들러 메서드가 늘어나 로직이 복잡해진다.

2. @RestControllerAdvice 애너테이션의 사용

: 클래스 레벨에 추가한다.

  • 예외 처리 메서드만 담긴 클래스에 @RestControllerAdvice를 추가해 예외 처리 메서드를 여러 Controller 클래스와 공유해 사용할 수 있다.
  • 예외 처리 공통화

비즈니스적인 예외 던지기 및 예외 처리

체크 예외와 언체크 예외

  1. 체크 예외(Checked Exception) : 예외를 잡아서 구체적인 처리가 필요한 예외
    • ClassNotFoundException
  2. 언체크 예외(Unchecked Exception) : 예외를 잡아서 명시적인 어떠한 처리를 할 필요가 없는 예외
    • 개발자의 실수로 발생한 RuntimeException을 상속한 예외들
    • NullPointerException, ArrayIndexOutOfBoundsException

개발자가 의도적으로 예외를 던질 수 있는 상황

  1. 백엔드 서버와 외부 시스템과의 연동에서 발생하는 에러 처리
    • 사용자사 돈을 송금하려 했을 때, 잔고 부족으로 송금에 실패하였다. 이때는 서버의 문제가 아닌 사용자의 문제임으로 의도적으로 예외를 던져 사용자에게 실패의 이유를 알려준다.
  2. 시스템 내부에 조회하려는 리소스가 없는 경우
    • 데이터베이스의 회원 정보를 조회하려 했으나 해당하는 회원 정보가 없을 경우, 서비스 계층에서 의도적으로 예외를 던져 사용자에게 회원 정보가 없음을 알려준다.

의도적으로 예외를 던지고 받는 방법(throw/catch)

예외는 메서드를 호출한 지점으로 던져진다. 즉, 서비스 계층의 메서드는 API계층인 Controller의 핸들러 메서드를 이용하므로 서비스 계층에서 던져진 예외는 Controller의 핸들러 메서드가 잡아 처리할 수 있다.

💡 예외 처리를 공통화 한 클래스가 있을 경우에는 서비스 계층에서 던져진 예외를 예외 처리 클래스가 잡아 처리한다.

사용자 정의 예외 처리

추상적인 예외가 아닌 경우, 구체적으로 표현할 수 있도록 사용자 정의 예외를 만들어 예외를 던질 수 있다.

  • EnumException Code를 정의해 클라이언트에게 표현할 것들을 작성한다.
public enum ExceptionCode { 
    MEMBER_NOT_FOUND(404, "Member Not Found"),
    METHOD_NOT_ALLOWED(405, "Method Not Allowed"),
    INTERNAL_SERVER_ERROR(500, "Internal Server Error");

    @Getter
    private int status;

    @Getter
    private String message;

    ExceptionCode(int status, String message) {
        this.status = status;
        this.message = message;
    }
}
  • 비즈니스 로직에서 발생하느 다양한 유형의 예외를 추가해 사용할 수 있다.
profile
🧑‍💻백엔드 개발자, 조금씩 꾸준하게

0개의 댓글