Spring의 Global 예외 처리와 에러 메시지 관리

coldrice99·2024년 10월 30일
0
post-thumbnail

Spring에서는 예외 처리를 좀 더 편리하게 관리하고, 사용자에게 전달할 에러 메시지를 체계적으로 관리할 수 있는 기능을 제공합니다. 이를 통해 코드의 중복을 줄이고 유지보수를 쉽게 만들며, 효율적인 에러 메시지 관리는 사용자에게 명확한 피드백을 제공할 수 있습니다.


1. Spring의 글로벌 예외 처리

Spring은 애플리케이션 전체에서 발생하는 예외를 한 곳에서 처리할 수 있도록 @ControllerAdvice@ExceptionHandler라는 기능을 제공합니다. 이 기능을 활용하면 각 컨트롤러에서 예외 처리를 반복할 필요 없이, 전역적으로 예외를 관리할 수 있어 훨씬 간편합니다.

🌟 @ControllerAdvice로 전역 예외 처리하기
  • 역할: 모든 컨트롤러에서 발생하는 예외를 한 곳에서 처리할 수 있도록 도와줍니다.
  • 장점:
    • 예외 처리를 중앙 집중화하여 코드의 중복을 방지할 수 있습니다.
    • 공통된 예외 처리 로직을 한 곳에 모아 관리할 수 있어 유지보수성이 높아지고, 팀 내 다른 개발자와 일관된 예외 처리 방식을 공유할 수 있습니다.
🌟 @RestControllerAdvice 활용
  • 역할: @ControllerAdvice@ResponseBody를 결합한 형태로, RESTful 서비스에서 예외 발생 시 JSON 형태로 응답을 보내는 데 유용합니다.
🛠️ 예시 코드: GlobalExceptionHandler

아래는 @RestControllerAdvice@ExceptionHandler를 사용해 글로벌 예외 처리를 구현한 예시입니다. 특정 예외가 발생하면 정의한 HTTP 응답과 함께 에러 메시지를 전달합니다.

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler({IllegalArgumentException.class})
    public ResponseEntity<RestApiException> handleIllegalArgumentException(IllegalArgumentException ex) {
        RestApiException restApiException = new RestApiException(ex.getMessage(), HttpStatus.BAD_REQUEST.value());
        return new ResponseEntity<>(restApiException, HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler({NullPointerException.class})
    public ResponseEntity<RestApiException> handleNullPointerException(NullPointerException ex) {
        RestApiException restApiException = new RestApiException(ex.getMessage(), HttpStatus.NOT_FOUND.value());
        return new ResponseEntity<>(restApiException, HttpStatus.NOT_FOUND);
    }
}

2. 에러 메시지 관리하기

예외를 처리할 때 에러 메시지를 코드에 직접 작성하지 않고, properties 파일을 사용해 관리하면 메시지 변경이나 다국어 지원이 쉬워집니다. Spring에서는 messages.properties 파일에 에러 메시지를 작성하고, 이 파일의 메시지를 MessageSource를 통해 불러와 사용할 수 있습니다.

🌟 메시지 파일 예시: messages.properties

에러 메시지를 properties 파일에 정의해 두면, 언제든지 메시지를 업데이트하거나 다국어로 확장할 수 있습니다.

below.min.my.price=최저 희망가는 최소 {0}원 이상으로 설정해 주세요.
not.found.product=해당 상품이 존재하지 않습니다.
🌟 MessageSource로 에러 메시지 불러오기

MessageSource를 통해 에러 메시지를 키 값과 매개변수로 불러올 수 있습니다. 예를 들어, 아래와 같이 최소 가격을 설정하는 메시지를 가져올 수 있습니다.

@Autowired
private MessageSource messageSource;

public ProductResponseDto updateProduct(Long id, ProductMypriceRequestDto requestDto) {
    if (requestDto.getMyprice() < MIN_MY_PRICE) {
        throw new IllegalArgumentException(
            messageSource.getMessage("below.min.my.price", new Object[]{MIN_MY_PRICE}, Locale.getDefault())
        );
    }
    // ...
}

3. 커스텀 예외 클래스 만들기

예외를 좀 더 구체적으로 다루기 위해 커스텀 예외 클래스를 만들 수도 있습니다. 이렇게 하면 특정 상황에 맞는 메시지를 보다 직관적으로 전달할 수 있습니다.

public class ProductNotFoundException extends RuntimeException {
    public ProductNotFoundException(String message) {
        super(message);
    }
}
커스텀 예외 처리 예시

ProductNotFoundException 예외가 발생할 때도, 글로벌 예외 핸들러를 통해 에러 응답을 관리할 수 있습니다.

@ExceptionHandler({ProductNotFoundException.class})
public ResponseEntity<RestApiException> handleProductNotFoundException(ProductNotFoundException ex) {
    RestApiException restApiException = new RestApiException(ex.getMessage(), HttpStatus.NOT_FOUND.value());
    return new ResponseEntity<>(restApiException, HttpStatus.NOT_FOUND);
}

결론

  • 글로벌 예외 처리는 모든 컨트롤러에서 발생하는 예외를 한 곳에서 처리하도록 하여 코드 중복을 방지하고 유지보수를 용이하게 합니다.
  • 에러 메시지 관리는 properties 파일을 통해 메시지를 외부화하고 MessageSource를 사용하여 다국어와 상황에 맞는 에러 메시지를 제공합니다.
profile
서두르지 않으나 쉬지 않고

0개의 댓글