繁体   English   中英

响应正文为空时,“IllegalStateException:仅允许一个连接接收订阅者”

[英]"IllegalStateException: Only one connection receive subscriber allowed" when response body is empty

我有一个 Spring Boot 2.3.1 项目,我在其中使用 WebClient 调用远程服务。

远程服务不是很可靠,往往会返回 500 错误,有无响应体。 我的目标是抛出一个包含响应正文(或默认消息)的自定义异常,以便我可以记录它,这是我的代码:

      webClient.get()
          .uri(targetServiceUri)
          .retrieve()
          .onStatus(HttpStatus::is5xxServerError, clientResponse ->
              clientResponse.bodyToMono(String.class)
                  .flatMap(error ->
                      Mono.error(new MyCustomServiceException(error))
                  )
          )
          .toEntity(String.class)
          .block();

我使用wiremock进行了2个测试,第一个有效:

  @Test
  void shouldThrowCustomExceptionWhenServiceReturns500ServerErrorWithNoBody() {
    setStubForInValidCheckCall(HttpStatus.INTERNAL_SERVER_ERROR,"{'Error':'invalid request'}");

    Throwable thrown =
        catchThrowable(() -> myClient.performComplianceCheck(getCompany()));

    assertThat(thrown)
        .isInstanceOf(MyCustomServiceException.class)
        .hasMessageContaining("{'Error':'invalid request'}");
  }
  
   private void setStubForInValidCheckCall(HttpStatus httpStatus, String body) {

    var response= aResponse().withStatus(httpStatus.value());

    if(body!=null){
      response=response.withBody(body);
    }

    stubFor(
        get(urlPathMatching("/targetCompliance"))
            .willReturn(response));
  }

但是,响应为 500 但没有正文(或者如果它是空字符串)的第二个测试失败并显示"java.lang.IllegalStateException: Only one connection receive subscriber allowed.

  @Test
  void shouldThrowCustomExceptionWhenServiceReturns500ServerErrorWithNoBody() {
    setStubForInValidCheckCall(HttpStatus.INTERNAL_SERVER_ERROR,null);

    Throwable thrown =
        catchThrowable(() -> myClient.performComplianceCheck(getCompany()));

    assertThat(thrown)
        .isInstanceOf(MyCustomServiceException.class)
        .hasMessageContaining("service returned status 500");
  }

我正在努力理解为什么会发生这种情况,以及如何解决它..

是“正常的”吗? 还是我遗漏了一些明显的东西(我的测试有问题吗?)?

我找到了一种解决方法,但它根本感觉不到“webFlux-y”,而且我仍然不明白为什么会发生Only one connection receive subscriber allowed

try {   
 ResponseEntity<String> responseEntity =
      webClient.get()
          .uri(targetServiceUri)
          .retrieve()
          .toEntity(String.class)
          .block();
}
catch (WebClientException e) {

  if(e instanceof InternalServerError){
    var internalServerError=(InternalServerError) e;

    if(internalServerError.getStatusCode().is5xxServerError()){

      var respBody=internalServerError.getResponseBodyAsString();

      if(StringUtils.isEmpty(respBody)){
        respBody=MY_STANDARD_MESSAGE +internalServerError.getRawStatusCode() ;
      }

      throw new MyCustomServiceException(respBody);

    }

  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM