Spring/스프링으로 시작하는 리액티브 프로그래밍

[Spring WebFlux] 예외 처리

꾸준함. 2024. 9. 16. 14:58

서론

Spring MVC 기반의 애플리케이션에서는 @ExceptionHandler 혹은 @ControllerAdvice 등의 애너테이션을 이용하여 예외 처리를 진행했습니다.

Spring WebFlux 기반의 애플리케이션에서도 두 애너테이션을 사용 가능하지만 이번 게시글에서는 Spring WebFlux 전용 예외 처리 기법에 대해 간단하게 정리해 보겠습니다.

 

Reactor에서 제공하는 에러 처리 Operator를 이용한 예외 처리

  • 자주 사용하는 Operator로 error, onErrorReturn, onErrorResume, onErrorContinue, retry가 있으며 해당 Operator들을 통해 inline 예외 처리 수행
    • 사용하기 쉽고 간편하지만
    • 클래스 내 여러 개의 Sequence가 존재할 때 각 Sequence마다 Operator를 일일이 추가해야 되고 중복 코드가 발생할 수 있음
    • 설명 및 예제는 기존 게시글 참고

 

위에서 언급한 다섯 가지 Operator 중 onErrorResume() Operator를 기준으로 예시를 들면 다음과 같습니다.

  • onErrorResume() Operator는 에러 이벤트 발생 시 에러 이벤트를 Downstream으로 전파하지 않고 대체 Publisher를 통해 여러 이벤트에 대한 대체 값을 emit 하거나 발생한 에러 이벤트를 wrapping 한 후에 다시 에러 이벤트를 발생시키는 역할


 

부연 설명

  • onErrorResume() Operator의 첫 번째 파라미터는 처리할 Exception 타입
    • 자바의 try-catch 문에서 catch 문에 Exception 클래스를 지정하는 것과 유사

 

  • onErrorResume()의 두 번째 파라미터는 대체할 Publisher의 Sequence
  • 첫 번째 onErrorResume() Operator는 BusinessLogicException 타입의 예외 발생 시 ErrorResponse 클래스에 HttpStatus 정보와 에러 메시지를 추가해서 응답으로 전송
  • 두 번째 onErrorResume() Operator는 BusinessLogicException 타입 이외의 Exception이 발생할 경우 역시 ErrorResponse 클래스에 HttpStatus 정보와 에러 메시지를 추가해서 응답으로 전송

 

ErrorWebExceptionHandler를 이용한 글로벌 예외 처리

  • Reactor에서 제공하는 에러 처리 Operator들의 단점인 중복 코드를 보완하기 위해 Global Exception Handler를 별도로 작성할 수 있음
  • Spring MVC의 @ControllerAdvice와 유사


 

부연 설명

  • Reactor에서 제공하는 예외 처리 Operator로 처리되지 않는 Exception을 글로벌 수준에서 처리하기 위한 Global Exception Handler 
    • ErrorWebExceptionHandler 구현체
    • ErrorWebExceptionHandler 인터페이스의 추상 메서드인 handle 추상 메서드를 구현하고
    • handle 메서드의 첫 번째 파라미터를 통해 ServerWebExchange 객체로 반환하도록 설정 가능
    • handle 메서드의 두 번째 파라미터로 발생한 예외 처리 가능

 

  • SpringBoot의 ErrorWebFluxAutoConfiguration을 통해 등록된 DefaultErrorWebExceptionHandler Bean의 우선순위보다 높은 우선순위인 -2 지정
  • bufferFactory() 메서드를 통해 BufferFactory 인터페이스의 구현 객체를 생성
    • BufferFactory는 DataBuffer를 위한 팩토리로서 response body를 작성하는 데 사용
    • response body의 content-type이 JSON 포맷임을 response header에 추가

 

  • 비즈니스 로직 처리 중 발생하는 예외와 Valdiation 처리 중 발생하는 Exception을 구분해서 ErrorResponse 구성
  • ErrorResponse 객체를 DataBuffer로 wrapping 하여 response body 구성 가능
  • writeWith() 메서드를 통해 파라미터로 지정한 Mono로 response body를 작성

 

참고

  • 스프링으로 시작하는 리액티브 프로그래밍 (황정식 저자)
반응형