Reputation: 2500
Spring docs says it is required to configure http client for WebClient manually to set timeouts: https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-client-builder-reactor-timeout.
But since WebClient returns reactive Mono, it's possible (api-wise) to apply .timeout
method.
Does it have the same effect?
Moreover, when one uses .timeout
method, Reactor's TimeoutException
is expected. Will the same error appear in the stream if configuration is done manually i.e. will doOnError(TimeoutException.class, ...)
work?
Upvotes: 3
Views: 20687
Reputation: 2500
My findings
Setting a timeout in a http client specific way will lead to http client specific exception i.e. WebClient
doesn't wrap exceptions:
@Test
void test() {
var host = "localhost";
var endpoint = "/test";
var port = 8089;
var timeout = Duration.ofSeconds(3);
WireMockServer wireMockServer = new WireMockServer(wireMockConfig().port(8089));
wireMockServer.start();
WireMock.configureFor(host, wireMockServer.port());
WireMock.stubFor(get(urlEqualTo(endpoint))
.willReturn(aResponse().withFixedDelay((int) timeout.toMillis())));
HttpClient httpClient = HttpClient.create()
.tcpConfiguration(client ->
client.doOnConnected(conn -> conn
.addHandlerLast(new ReadTimeoutHandler((int) (timeout.toSeconds() / 2)))
.addHandlerLast(new WriteTimeoutHandler((int) (timeout.toSeconds() / 2)))));
WebClient webClient = WebClient.builder()
.baseUrl(format("http://%s:%d", host, port))
.clientConnector(new ReactorClientHttpConnector(httpClient)).build();
webClient.get().uri(endpoint).retrieve().bodyToMono(Recommendation.class).block();
}
This will lead to io.netty.handler.timeout.ReadTimeoutException
.
.timeout(timeout.dividedBy(2)).block()
leads to regular TimeoutException
(java.util.concurrent
) but it's still an open question whether a web client takes care about connections afterwards (probably not).
My solution is to use http client specific configuration to ensure native and correct way to utilize connections while adding new handler that wraps http client related exception into more generic ones (or java.util.concurrent.TimeoutException
) so that WebClient
clients won't depend on provider exceptions.
Upvotes: 5