我想在我的应用程序中将 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();
Run Code Online (Sandbox Code Playgroud)
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();
Run Code Online (Sandbox Code Playgroud)
我想要的只是打印日志并返回对象。但是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)```
Run Code Online (Sandbox Code Playgroud)
阅读源代码后,我发现异常是由reactor.netty.http.client打印的。而且我确信我已经捕获了异常,所以整个异常堆栈信息对我来说是无用的。我需要做的就是禁用日志。
<logger name="reactor.netty.http.client" level="OFF"/>
| 归档时间: |
|
| 查看次数: |
2726 次 |
| 最近记录: |