[스프링 부트 핵심 가이드] 정리 6주차(2)

AmeriKano·2023년 6월 19일
0

이번주 정리 내용이 좀 길어져서 분리했다.
이전 글 링크


스프링 부트에서의 예외 처리

웹 서비스 어플리케이션에서는 외부에서 들어오는 요청에 담긴 데이터를 처리하는 경우가 많다. 그 과정에서 예외가 발생하면 예외를 복구하여 정상으로 처리하기보다는 요청을 보낸 클라이언트에 어떤 문제가 발생했는지를 전달하는 경우가 더 많다.

예외가 발생했을 때 클라이언트에 오류를 전달하려면 결국 컨트롤러로 전달해야 한다. 스프링 부트에서는 크게 두 가지의 방식으로 처리한다.

  • @RestControllerAdvice@ExceptionHandler 을 이용해 모든 컨트롤러의 예외 처리
  • @ExceptionHandler 을 이용해 특정 컨트롤러의 예외 처리
@RestControllerAdvice
public class CustomExceptionHandler {
	...
    @ExceptionHandler(value = RuntimeException.class)
    public ResponseEntity<?> handleException(RuntimeException e, HttpServletRequest request) {
    	...
    }
    ...
}

위처럼 클래스에 @RestControllerAdvice 를 지정해주면 @Controller@RestController 에서 발생하는 예외를 한 곳에서 관리하고 처리 가능하며, 패키지를 지정해서 예외를 관제하는 범위를 지정할 수도 있다. 그리고 @ExceptionHandler 에 처리하고 싶은 예외를 value 로 지정해주면 지정한 예외를 처리하는 메서드가 정의된다.
이렇게 구현하면 지정한 예외가 발생했을 때 응답으로 예외 처리 메소드를 실행하여 얻은 결과를 전달한다. 특정 컨트롤러에서만 예외를 처리하고 싶다면 @ExceptionHandler 가 달려 있는 메소드를 그 컨트롤러에 정의하면 된다.

예외 처리의 우선순위

동일하게 핸들러 메소드가 선언된 상태라면 조금 더 구체적인 예외 클래스가 선언된 쪽이 더 높은 우선순위를 갖게 된다. 다른 경우로는 글로벌 예외 처리와 컨트롤러 내의 예외 처리가 있을텐데, 이 경우에는 범위가 좁은 컨트롤러의 핸들러 메소드가 우선순위를 가진다.

커스텀 예외 처리

예외를 상속받고 별도의 메세지를 지정해주는 방식으로 커스텀 예외를 정의하여 사용할 수 있다. 예를 들으면 다음과 같다.

public class CustomException extends RuntimeException {
	
    private HttpStatus httpStatus;
    private ErrorCode errorCode;
    private String description;
    
    public CustomException(ErrorCode errorCode) {
    	this.errorCode = errorCode;
        this.httpStatus = errorCode.httpStatus;
        this.description = errorCode.description;
    }
}

public enum ErrorCode {
	
    NOT_ENOUGH_MONEY(HttpStatus.BAD_REQUEST, "잔액이 부족합니다.");
    // 이외에 다양한 에러들을 정의하여 사용
    
    private HttpStatus httpStatus;
    private String description;
}

다른 기본 구현된 예외를 던지는 것과 같은 방법으로 예외 처리하고 싶은 부분에 throw new CustomException() 을 작성해주면 된다.

profile
똑똑한 사람이 되게 해주세요

0개의 댓글