Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch timeout exception in Spring WebClient?

Currently I am writing a method that using WebClient to send POST request to another service.

private Mono<GameEntity> callApplication(GameEntity gameEntity) throws URISyntaxException {
    WebClient client = WebClient.create();
    for(int i=0;i<NUM_OF_RETRY;++i) {
        String port = strategy.getNextInstancePort();
        URI uri = new URI(String.format("http://localhost:%s/game/add", port));
        try {
            Mono<GameEntity> response = client.post()
                    .uri(uri)
                    .contentType(MediaType.APPLICATION_JSON)
                    .body(Mono.just(gameEntity), GameEntity.class)
                    .retrieve()
                    .bodyToMono(GameEntity.class)
                    .timeout(Duration.ofSeconds(3))
            return response;
        } catch (WebClientRequestException e) {
            //....
        } catch (Exception e) {
            strategy.incrErrorCount(port);
        }
    }
    return null;
}

My approach is when the timeout occurs, we need to call another method strategy.incrErrorCount(port). But the webclient does not throw any exception that can be caught in catch (Exception e) block.

Is there any solution to access this method when timeout occurs?

like image 999
Andy Avatar asked Nov 29 '25 16:11

Andy


1 Answers

If you mean the timeout that happens due to

.timeout(Duration.ofSeconds(3))

Then timeout() operator has another signature

public final Mono<T> timeout(Duration timeout, Mono<? extends T> fallback)

From java doc:

Switch to a fallback Mono in case no item arrives within the given Duration. If the fallback Mono is null, signal a TimeoutException instead.

So, you can pass your strategy.incrErrorCount(port) into that method, so that line would look like this:

.timeout(Duration.ofSeconds(3), Mono.fromSupplier(() -> strategy.incrErrorCount(port)))
like image 173
kerbermeister Avatar answered Dec 02 '25 05:12

kerbermeister