spring-webflux - Spring WebFlux 的 WebClient 如何捕捉 Netty 的 ProxyConnectException 等异常

标签 spring-webflux

我想在我的应用程序中将Apache HttpComponents Client 更改为Spring WebFlux 的WebClient。但是我无法从Netty 中捕获异常,例如io.netty.handler.proxy.ProxyConnectException .

我试过 doOnError运算符,但对于这些异常,它们无法被捕获。

var timeout = Duration.ofSeconds(3);
        if (proxy != null) {
            HttpClient httpClient = HttpClient.create()
                .tcpConfiguration(tcpClient ->
                    tcpClient.proxy(py -> py.type(ProxyProvider.Proxy.HTTP).host(proxy.getHost()).port(proxy.getPort()).username(proxy.getUser()).password(tmp -> proxy.getPass())).doOnConnected(conn -> conn
                        .addHandlerLast(new ReadTimeoutHandler((int) (timeout.toSeconds() / 2)))
                        .addHandlerLast(new WriteTimeoutHandler((int) (timeout.toSeconds() / 2)))));
            ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);

            ExchangeStrategies strategies = ExchangeStrategies
                .builder()
                .codecs(clientDefaultCodecsConfigurer -> {
                    clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(objectMapper, MediaType.APPLICATION_JSON));
                    clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(objectMapper, MediaType.APPLICATION_JSON));

                }).build();

            WebClient webClient = WebClient
                .builder()
                .exchangeStrategies(strategies)
                .clientConnector(connector)
                .build();
            ClientResponse httpException = ClientResponse.create(org.springframework.http.HttpStatus.REQUEST_TIMEOUT).build();


      webClient
      .get()
      .uri("my_uri")
      .accept(MediaType.ALL)
      .header("my_header_key", "my_header_value")
      .exchange().doOnError(ProxyConnectException.class, throwable -> {
                    logger.warn("ProxyConnectException");
                })
      .onErrorReturn(httpException)
      .doOnError(ConnectTimeoutException.class, e -> {
                    logger.warn("ConnectTimeoutException");
                })
      .doOnError(ReadTimeoutException.class, e -> {
                    logger.warn("ReadTimeoutException");
                })
      .doOnError(SSLException.class, e -> {
                    logger.warn("SSLException");
                })
      .doOnError(Exception.class, e -> {
                    logger.warn("Exception");
                })
      .onErrorReturn(httpException)
      .block();

我想要的只是打印日志并返回 httpException对象。但结果不仅是我所期望的,我的日志被打印出来,我的对象被返回,但我也可以看到一些异常信息如下。有什么办法可以避免这些异常?
io.netty.handler.proxy.ProxyConnectException: http, none, /XXXX:XX => XXXX:XX, timeout
    at io.netty.handler.proxy.ProxyHandler$2.run(ProxyHandler.java:201)
    at io.netty.util.concurrent.PromiseTask$RunnableAdapter.call(PromiseTask.java:38)
    at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:127)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
    at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:335)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
    at java.base/java.lang.Thread.run(Thread.java:834)
ERROR [reactor-http-epoll-5] HttpClientConnect --- [id: 0x3610bfd0, L:/XXXX:XX ! R:XXXX/XXXX:XX] The connection observed an error
java.nio.channels.ClosedChannelException: null
    at io.netty.handler.ssl.SslHandler.channelInactive(...)(Unknown Source)```

最佳答案

阅读源代码后,我发现异常是由 打印的reactor.netty.http.client .而且我确定我已经捕获到异常,所以整个异常堆栈信息对我来说是无用的。我需要做的只是 禁用 日志。
<logger name="reactor.netty.http.client" level="OFF"/>

关于spring-webflux - Spring WebFlux 的 WebClient 如何捕捉 Netty 的 ProxyConnectException 等异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56039280/

相关文章:

spring-boot - spring-boot-webflux 中未使用配置的 ObjectMapper

java - 获取http响应代码和所有可用的正文

java - 在 Spring Boot 中使用 @EnableWebFluxSecurity 时出错

spring-webflux - 获取 web 客户端 web-flux 的响应时间

spring-boot - 使用 spring-security 和响应式(Reactive) spring 的自定义身份验证

spring-boot - 配置 Spring WebFlux WebClient 以使用自定义线程池

java - Spring web flux WebClient : Connection rest by peers, #block 因错误而终止。在以下站点观察到错误

java - Spring Webflux - 如何使用 Tuple3 将三个 Flux 对象聚合为 1

java - 使用 Spring Boot 2 WebClient,以线程安全/每个请求的方式,如何在每个请求发送 diff header ?

spring-security - 我如何为 spring webflux 应用程序配置 oauth2 资源服务器?