英文:
How to catch timeout exception in Spring WebClient?
问题
私下我正在编写一个方法,使用WebClient发送POST请求到另一个服务。
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;
}
我的方法是,当超时发生时,我们需要调用另一个方法 strategy.incrErrorCount(port)。但是WebClient不会抛出任何可以在 catch (Exception e) 块中捕获的异常。
在超时发生时,是否有任何解决方案来访问这个方法?
英文:
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?
答案1
得分: 1
如果你指的是由于以下代码而发生的超时:
.timeout(Duration.ofSeconds(3))
那么 timeout() 操作符还有另一种签名:
public final Mono<T> timeout(Duration timeout, Mono<? extends T> fallback)
根据 Java 文档的描述:
如果在给定的持续时间内没有收到任何项目,则切换到备用的 Mono。如果备用的 Mono 为 null,则抛出 TimeoutException。
因此,你可以将 strategy.incrErrorCount(port) 传递给该方法,那么该行代码将如下所示:
.timeout(Duration.ofSeconds(3), Mono.fromSupplier(() -> strategy.incrErrorCount(port)))
英文:
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)))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论