Spring WebFlux: 글로벌 예외 처리

김기현·2025년 8월 6일

Spring WebFlux

목록 보기
23/28

Spring WebFlux에서 글로벌 예외 처리를 구현하는 방법은 기존의 Spring MVC와 동일하게 @ControllerAdvice@ExceptionHandler를 사용하는 것이다.


@ControllerAdvice와 @ExceptionHandler 활용

@ControllerAdvice@Controller 애노테이션이 적용된 모든 클래스에 대한 전역적인 처리를 제공한다. 이 클래스 내부에 @ExceptionHandler애노테이션을 사용하여 특정 예외 타입에 대한 핸들링 로직을 정의할 수 있다.

1. @ControllerAdvice 클래스 생성

애플리케이션의 모든 예외를 처리할 @ControllerAdvice 클래스를 생성한다. 이 클래스는 @RestControllerAdvice로 선언하여 @ResponseDoby를 포함시킬 수도 있다.

@RestControllerAdvice
public class GlobalExceptionHandler {

    // 예외 처리 메서드를 작성
}

2. @ExceptionHandler를 이용한 예외 처리 메소드 작성

GlobalExceptionHandler 클래스 내부에 특정 예외를 처리할 메소드를 @ExceptionHandler와 함께 작성한다.
이 메소드는 예외 타입(ex: IllegalArgumentException)을 인자로 받으며, Mono<ResponseEntity<?>>를 반환한다.

@RestControllerAdvice
public class GlobalExceptionHandler {
    
    // 사용자 정의 예외 처리 
    @ExceptionHandler(IllegalArgumentException.class)
    public Mono<ResponseEntity<String>> handleIllegalArgumentException(IllegalArgumentException ex) {
        return Mono.just(ResponseEntity.badRequest().body("잘못된 요청입니다: " + ex.getMessage()));
    }
    
    // 일반적인 예외 처리
    @ExceptionHandler(Exception.class)
    public Mono<ResponseEntity<String>> handleAllExceptions(Exception ex) {
        // 모든 종류의 예외를 처리하는 핸들러
        return Mono.just(ResponseEntity.internalServerError().body("서버 오류가 발생했습니다: " + ex.getMessage()));
    }
}

위와 같이 IllegalArgumentException과 같은 특정 예외를 처리하는 핸들러와 그 외의 모든 예외를 처리하는 일반적인 핸들러를 함께 정의할 수 있다.


예시 코드

다음은 @ControllerAdvice를 사용하여 클로벌 예외 처리를 구현한 전체 예제이다.

// Controller
@RestController
public class InvalidExceptionController {

    @GetMapping("/users/{id}")
    public Mono<String> getUser(@PathVariable String id) {
        if ("유효하지 않은 ID".equals(id)) {
            // "invalid" ID에 대해 의도적으로 예외 발생
            return Mono.error(new IllegalArgumentException("유효하지 않은 사용자 ID입니다."));
        }
        return Mono.just("User " + id + " found");
    }
}

// Global Exception Handler
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(IllegalArgumentException.class)
    public Mono<ResponseEntity<String>> handleIllegalArgumentException(IllegalArgumentException ex) {
        // HTTP 400 Bad Request와 함께 에러 메시지 반환
        return Mono.just(ResponseEntity.badRequest().body("잘못된 요청: " + ex.getMessage()));
    }

    @ExceptionHandler(Exception.class)
    public Mono<ResponseEntity<String>> handleAllExceptions(Exception ex) {
        // HTTP 500 Internal Server Error와 함께 에러 메시지 반환
        return Mono.just(ResponseEntity.internalServerError().body("서버 오류: " + ex.getMessage()));
    }
}

이 예제에서 /users/invalid 엔드포인트로 요청이 오면 InvalidExceptionControllerIllegalArgumentException을 발생시킨다.
이 예외는 GlobalExceptionHandlerhandleIllegalArgumentException메소드에 의해 감지되어 400 응답이 클라이언트에게 반환된다.

profile
백엔드 개발자를 목표로 공부하는 대학생

0개의 댓글