스프링 예외 처리

장현진·2022년 1월 30일
1

Spring

목록 보기
1/3

스프링에서 예외처리는 크게 3가지 방법이 있다.

1. 메서드 단위에서 try/catch를 통해 처리하는 방법.
2. 컨트롤러단에서 @ExceptionHandler를 이용해서 처리하기
3. Global level에서 컨트롤러 이후 Client에게 전달되기 직전 처리하기.


1번의 경우 try-catch를 반복적으로 사용하는 경우 가독성이 떨어지고 중복코드가 많아 진다




2번의 경우 @ExceptionHandler는 @Controller, @RestController가 적용된 Bean내에서 발생하는 예외를 잡아서 하나의 메서드에서 처리해주는 기능을 한다.

이는 빈 내에서 발생하는 특정 예외를 처리해주는 기능을 지원한다.



주의사항/알아 둘 것
  1. Controller, RestController에만 적용가능하다. (@Service같은 빈에서는 안됨.)

  2. 리턴 타입은 자유롭게 해도 된다. (Controller내부에 있는 메서드들은 여러 타입의 response를 할 것이다. 해당 타입과 전혀다른 리턴 타입이어도 상관없다.)

  3. @ExceptionHandler를 등록한 Controller에만 적용된다. 다른 Controller에서 NullPointerException이 발생하더라도 예외를 처리할 수 없다.

  4. 메서드의 파라미터로 Exception을 받아왔는데 이것 또한 자유롭게 받아와도 된다.




또한 이방법은 컨트롤러마다 @ExceptionHandler를 정의해 중복코드가 많이 발생하게 된다 이를 막기위해 3번째 방법인
@ControllerAdvice를 사용한다.

@ExceptionHandler가 하나의 클래스에 대한 것이라면, @ControllerAdvice는 모든 @Controller 즉, 전역에서 발생할 수 있는예외를 잡아 처리해주는 annotation이다.

위와 같이 새로운 클래스파일을 만들어서 annotation을 붙이기만 하면 된다. 그 다음에 @ExceptionHandler로 처리하고 싶은 예외를 잡아 처리하면 된다.

@ControllerAdvice를 사용함으로써 @ExceptionHandler를 중복사용하지 않고 한군데서 관리 할수 있게 된다.



실제 예외처리

우선 @ControllerAdvice를 정의한다.

@ControllerAdvice
public class CustomExceptionHandler {

 @ExceptionHandler(Exception.class)
  public ResponseEntity<ErrorResponseEntity> handleAll(Exception ex){
      ErrorResponseEntity response = new ErrorResponseEntity(ErrorCode.INTERNAL_SERVER_ERROR , ex.getMessage());
      return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
  }

모든예외처리를 받는 handeAll을 정의 하였다. ErrorResponseEntity를 추가로 정의하여 에러 코드를 객체형태로 받아서 볼수 있게끔 정의 하였다.

  
 import lombok.Data;

@Data
public class ErrorResponseEntity {
    private int status;
    private String code;
    private String message;
    private String detail;

    public ErrorResponseEntity(ErrorCode errorCode , String detail) {
        this.status = errorCode.getStatus();
        this.code = errorCode.getCode();
        this.message = errorCode.getMessage();
        this.detail = detail;
    }
}

그후 본인이 사용할 CustomException을 정의한다.


public class FriendException extends RuntimeException {

  // 1. 매개 변수가 없는 기본 생성자
  public FriendException() {

  }

  // 2. 예외 발생 원인(예외 메시지)을 전달하기 위해 String 타입의 매개변수를 갖는 생성자
  public FriendException(String message) {
      super(message); // RuntimeException 클래스의 생성자를 호출합니다.
  }
}

우리프로젝트에 친구관련 api에 적용할 예외처리를 커스텀 하였다.
예외처리를 커스텀하여서 써야하는가 자바에서 제공하는것으로 충분한가 에 대해서는 생각해볼만한 글이 여기 있다

글을 마치며

아직 예외처리에 대해 부족한 부분이 있고 링크한 글을 참고 하였을때는 예외처리는 커스텀 하여 사용하는 것이 협업 단계에서 알아보기 쉽고 응집도가 높을 것으로 생각된다.

다음에는 예외처리 리턴시 HttpStatus.INTERNAL_SERVER_ERROR등 에러코드에 대해 알아 보려 한다.

0개의 댓글