如何使用WebClient中的检索处理500个错误代码

问题描述

我已经阅读了很多文档以及与此有关的其他stackoverflow问题,但似乎无法使我的代码正常工作。

基本上,我有一个WebClient发出POST请求。

  • 如果响应状态为200,则使用另一个WebClient再次调用另一个端点。在第二次webclient调用之后,返回一个字符串。
  • ELSE我只是从方法中返回一个字符串,例如“无法创建订单。”

足够简单。 (这都是在单独的线程fyi中完成的,而不是在主线程中完成的。)

但是我注意到,如果我确实得到了500错误代码,则WebClient会引发异常。我想做的就是捕获异常并优雅地处理该异常,并返回一个字符串,例如“错误调用第一个端点等”。

这是我到目前为止所拥有的:

private String generateOrder(ImportedOrderDetails importedOrderDetails)
   {
    
      Order requestBody = generateRequestBody(importedOrderDetails);
      OrderResponse responseForCreatingOrder = orderWebClient()
                                                       .post()
                                                       .body(Mono.just(requestBody),Order.class)
                                                       .retrieve()
                                                       .bodyToMono(OrderResponse.class)
                                                       .block();

      
      if (responseForCreatingOrder.getResponseStatus().equals(SUCCESS))
      {...other call using different webclient}
      else{ return "Error creating order."}

当响应状态为200,但响应状态为500时,此方法工作正常。 OrderResponse是一个自定义对象。 orderWebClient()只是一种返回包含baseUrl和标头等的预构建WebClient的方法。

我遇到了这个: Spring WebClient - How to handle error scenarios我确实尝试实现了它,但是由于不断获取以下内容,所以无法弄清楚将block方法放在哪里:

reactor.core.Exceptions$ReactiveException: java.lang.Exception
    at reactor.core.Exceptions.propagate(Exceptions.java:393)
    at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:97)
    at reactor.core.publisher.Mono.block(Mono.java:1680)

我不得不稍微修改一下代码以尝试实现该问题的答案:

   private Mono<? extends Throwable> handleError(String message) {
      log.error("====---"+message);
      return Mono.error(Exception::new);
   }

   private String generateOrder(ImportedOrderDetails importedOrderDetails)
   {
      Order requestBody = generateRequestBody(importedOrderDetails);
      Mono<OrderResponse> responseForCreatingDemo = orderWebClient()
                                                       .post()
                                                       .body(Mono.just(requestBody),Order.class)
                                                       .retrieve()
                                                       .onStatus(
                                                          (HttpStatus::is5xxServerError),(it -> handleError(it.statusCode().getReasonPhrase()))
                                                       )
                                                       .bodyToMono(OrderResponse.class);


      
      System.out.println("-=-"+responseForCreatingDemo);
      if (responseForCreatingOrder != null && responseForCreatingOrder.block().getHeader().getResponseStatus().equals(SUCCESS)){...}

错误来自if条件中的.block部分。我相信这是一件很琐碎的事情,而且缺少大局。

有什么建议吗?

解决方法

您似乎有两种状态:

  1. 由协议本身定义的Http状态(请参见HTTP response status codes
  2. 特定于您正在处理的应用程序的某些内容,封装在OrderResponse类中。

因此您必须处理两个“错误”而不是一个,可能的解决方案中的一个 看起来像

.retrieve()
.bodyToMono(OrderResponse.class)
// 4xx,5xx errors and return "Unable to create order" String instead
.onErrorContinue(WebClientResponseException.class,(ex,v) -> 
    Mono.just("Unable to create order"))
// if application specific status is not "ok" return "Unable to create order"
.map(it -> it.ok ? "Ok response" : "Unable to create order")
.block();

请注意,此代码示例将忽略异常,甚至不会记录该异常

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...