javaspringspring-webfluxreactive-programmingproject-reactor

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?


Solution

  • 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)))