From 1717ef715c028662321515cfdb386cf1ad120450 Mon Sep 17 00:00:00 2001 From: giampaolo Date: Sat, 5 Apr 2025 14:19:06 +0200 Subject: [PATCH] Fix throws only ResourceAccessException on timeout CancellationExceptions are thrown instead of the expected ResourceAccessException during timeout scenarios. Handle the CancellationExceptions in order to throw an ResourceAccessException when timeout occurred Closes gh-33973 Signed-off-by: giampaolo --- .../springframework/http/client/JdkClientHttpRequest.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java index 060bef8dde28..1e7068263d73 100644 --- a/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java @@ -96,12 +96,13 @@ public URI getURI() { @Override protected ClientHttpResponse executeInternal(HttpHeaders headers, @Nullable Body body) throws IOException { CompletableFuture> responseFuture = null; + TimeoutHandler timeoutHandler = null; try { HttpRequest request = buildRequest(headers, body); responseFuture = this.httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream()); if (this.timeout != null) { - TimeoutHandler timeoutHandler = new TimeoutHandler(responseFuture, this.timeout); + timeoutHandler = new TimeoutHandler(responseFuture, this.timeout); HttpResponse response = responseFuture.get(); InputStream inputStream = timeoutHandler.wrapInputStream(response); return new JdkClientHttpResponse(response, inputStream); @@ -136,6 +137,9 @@ else if (cause instanceof IOException ioEx) { throw (message == null ? new IOException(cause) : new IOException(message, cause)); } } + catch (CancellationException ex) { + throw new HttpTimeoutException("Request timed out"); + } } private HttpRequest buildRequest(HttpHeaders headers, @Nullable Body body) { @@ -224,6 +228,7 @@ public ByteBuffer map(byte[] b, int off, int len) { private static final class TimeoutHandler { private final CompletableFuture timeoutFuture; + private boolean isTimeout=false; private TimeoutHandler(CompletableFuture> future, Duration timeout) { @@ -232,6 +237,7 @@ private TimeoutHandler(CompletableFuture> future, Dura this.timeoutFuture.thenRun(() -> { if (future.cancel(true) || future.isCompletedExceptionally() || !future.isDone()) { + this.isTimeout = true; return; } try {