Spring WebClient Bubbling Exception

dropKick·2024년 4월 18일

개발 이슈

목록 보기
9/14

개요

  • 사내 분할결제 서비스 구현에서 가맹점 통신 구현 시 WebClient를 통한 비동기 통신으로 사용
  • 비동기 요청 처리 중 Bubbling Exception 발생 확인

원인

✅ WebClient의 subscribe 프로세스에서 onDropped().. 한마디로 onStatus -> onProcess 흐름이 정상적으로 종료되지 않고 예외 발생
onDropped()가 호출되며 예외 발생 → Subscription 구독 스트림이 강제로 종료 이후 Netty에서 이미 할당 해제된 스트림을 다시 해제하려고 할 때 문제가 발생

onDropped() 호출 원인

  • onNext() 또는 onStatus() 처리 전 예외 발생
  • Mono.error()로 Reactor subscribe 체인 중단

해결법

doOnCancel()/doFinally()

webClient.get()
    .uri("https://example.com/api")
    .retrieve()
    .onStatus(HttpStatus::isError, response -> Mono.error(new RuntimeException("API 호출 실패")))
    .doOnCancel(() -> System.out.println("Request canceled"))
    .doFinally(signalType -> System.out.println("Request finalized with: " + signalType))
    .subscribe(response -> System.out.println("Response received"));
  • doOnCancel()/doFinally()를 통해 구독이 끊기는 경우 실행되는 로직을 추가하는 방법
  • 그런데 내가 원하는건 Mono 형태의 응답을 끝가지 받는거라 패스

onErrorResume()

webClient.get()
    .uri("https://example.com/api")
    .retrieve()
    .bodyToMono(String.class)
    .onErrorResume(error -> {
        System.out.println("Exception caught: " + error.getMessage());
        return Mono.just("Default response"); // 예외 발생 시 기본 값 반환
    })
    .subscribe(response -> System.out.println("Response: " + response));
  • Mono.error 대신 Mono.just로 에러 결과/기본 결과를 내려주는 방법
  • 에러가 발생하더라도 가맹점에 요청에 따른 응답 결과를 항상 내려줘야하기 때문에 선택
profile
안아줘요

0개의 댓글