当前位置: 首页 > 知识库问答 >
问题:

从Web客户端捕获返回Flux的PrematureCloseExc的异常

经佐
2023-03-14

如何捕获<code>reactor.netty.http.client。使用org.springframework.web.reactive.function.client时,过早关闭异常。WebClient来检索和无限reactor.core.publisher.Flux

为了重现这个问题,我创建了两个简单的Spring Boot应用程序。两者都基于org.springframework.boot: sping-boot-starter-web的

服务器代码是:

@RestController
public class TestserverRestController {

    @GetMapping(value="/huge-flux", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
    public Flux<Long> hugeFlux() {
        return Flux.range(1, Integer.MAX_VALUE).interval(Duration.ofSeconds(1));
    }

    @Autowired
    ConfigurableApplicationContext springContext;

    @GetMapping(value="/stop")
    public void stop() {
        springContext.close();
    }
}

客户代码是:

@Component
public class TestclientRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        Flux<Long> flux = WebClient.create().get()
                .uri("http://localhost:9000/huge-flux")
                .accept(MediaType.APPLICATION_STREAM_JSON)
                .retrieve()
                .bodyToFlux(Long.class);
        flux.subscribe(val -> System.out.printf("Value %d%n", val));
    }
}

点击<code>http://localhost:9000/stop在web浏览器中,客户端被终止,并且此错误出现在客户端的控制台上。

WARN 15635 --- [ctor-http-nio-2] reactor.netty.channel.FluxReceive : [id: 0x82a94759, L:0.0.0.0/0.0.0.0:61812] An exception has been observed post termination, use DEBUG level to see the full stack: reactor.core.Exceptions$ErrorCallbackNotImplemented: reactor.netty.http.client.PrematureCloseException: Connection prematurely closed DURING response

我希望能够捕获该错误,以便我可以恢复。(在我的真实项目中,如果一个服务器失败,将有备用服务器可以连接。)

我在客户端尝试的事情包括:

flux.doOnCancel(()-> log.warning("CANCEL"));
flux.doOnTerminate(()-> log.warning("TERMINATE"));
flux.doOnComplete(()-> log.warning("COMPLETE"));
flux.doOnDiscard(Object.class, (o)-> log.warning("DISCARD"));
flux.doOnError((e)-> log.warning("ERROR"));

但是,当服务器终止时,不会打印这些日志消息。

共有1个答案

乜思淼
2023-03-14

通过替换<代码>通量。客户端代码中的subscribe()行包含:

            flux.subscribe(
                    val -> System.out.printf("Value %d%n", val),
                    ex -> System.err.printf("ERROR CONSUMER [%s] %s", ex.getClass(), ex.getMessage()),
                    () -> System.err.printf("COMPLETE CONSUMER"));

错误使用者可以捕获该问题(打印“错误使用者”)。

 类似资料:
  • 我有一个从服务器端抛出的异常,我希望在客户端捕捉到这个异常。异常应该使用Jersey通过REST发送。这是我目前所掌握的: 定义我的异常:

  • 问题内容: 以下代码给出了编译错误,提示“意外运行”: 我知道,如果正常调用函数就可以获取返回值,而无需使用goroutine。或者我可以使用频道等 我的问题是为什么不能从goroutine中获取像这样的返回值。 问题答案: 严格的答案是您 可以 做到。这可能不是一个好主意。下面的代码可以做到这一点: 这将产生一个新的goroutine,它将进行计算,然后将结果分配给。问题是:您将如何使用原始go

  • 因此,上面的代码是一个Spring MVC控制器方法,以1秒的间隔发出0~10个数字。 这是我的客户代码。 问题是,客户端程序一次打印出0~10个,而不是以1秒的间隔逐个打印。 所以,它不会逐个打印来自服务器的值,而是在流完成时打印所有接收到的值。 有人能帮我解决这个问题吗? 谢啦

  • 我在一个基于XML的spring上下文文件中定义了一个骆驼上下文。有一条路由正在由SOAP(XML)web服务客户端bean调用。在调用路由时,它抛出一些异常,客户端接收到骆驼异常,而不是原始异常。 Camel在异常时对客户端的响应如下所示 预期响应应该是任何异常的原始异常消息 这是我的骆驼路线定义 我尝试使用camel onException但没有成功:(

  • 下一个metod在TokenService类中。