Skip to content

Commit 86c337a

Browse files
committed
Fix throws only ResourceAccessException on timeout spring-projects#33973
CancellationExceptions are thrown instead of the expected ResourceAccessException during timeout scenarios. Handle the CancellationExceptions in order to throw an ResourceAccessException when timeout occurred Closes spring-projectsgh-33973
1 parent eee45c3 commit 86c337a

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

Diff for: spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java

+12-6
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,8 @@ class JdkClientHttpRequest extends AbstractStreamingClientHttpRequest {
7070

7171
private final @Nullable Duration timeout;
7272

73-
7473
public JdkClientHttpRequest(HttpClient httpClient, URI uri, HttpMethod method, Executor executor,
75-
@Nullable Duration readTimeout) {
74+
@Nullable Duration readTimeout) {
7675

7776
this.httpClient = httpClient;
7877
this.uri = uri;
@@ -81,7 +80,6 @@ public JdkClientHttpRequest(HttpClient httpClient, URI uri, HttpMethod method, E
8180
this.timeout = readTimeout;
8281
}
8382

84-
8583
@Override
8684
public HttpMethod getMethod() {
8785
return this.method;
@@ -92,16 +90,15 @@ public URI getURI() {
9290
return this.uri;
9391
}
9492

95-
9693
@Override
9794
protected ClientHttpResponse executeInternal(HttpHeaders headers, @Nullable Body body) throws IOException {
9895
CompletableFuture<HttpResponse<InputStream>> responseFuture = null;
96+
TimeoutHandler timeoutHandler = null;
9997
try {
10098
HttpRequest request = buildRequest(headers, body);
10199
responseFuture = this.httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream());
102-
103100
if (this.timeout != null) {
104-
TimeoutHandler timeoutHandler = new TimeoutHandler(responseFuture, this.timeout);
101+
timeoutHandler = new TimeoutHandler(responseFuture, this.timeout);
105102
HttpResponse<InputStream> response = responseFuture.get();
106103
InputStream inputStream = timeoutHandler.wrapInputStream(response);
107104
return new JdkClientHttpResponse(response, inputStream);
@@ -136,6 +133,13 @@ else if (cause instanceof IOException ioEx) {
136133
throw (message == null ? new IOException(cause) : new IOException(message, cause));
137134
}
138135
}
136+
catch (CancellationException ex) {
137+
if(timeoutHandler != null && timeoutHandler.isTimeout){
138+
throw new HttpTimeoutException("Request timed out");
139+
}
140+
Throwable cause = ex.getCause();
141+
throw new IOException(cause.getMessage(), cause);
142+
}
139143
}
140144

141145
private HttpRequest buildRequest(HttpHeaders headers, @Nullable Body body) {
@@ -224,6 +228,7 @@ public ByteBuffer map(byte[] b, int off, int len) {
224228
private static final class TimeoutHandler {
225229

226230
private final CompletableFuture<Void> timeoutFuture;
231+
boolean isTimeout=false;
227232

228233
private TimeoutHandler(CompletableFuture<HttpResponse<InputStream>> future, Duration timeout) {
229234

@@ -232,6 +237,7 @@ private TimeoutHandler(CompletableFuture<HttpResponse<InputStream>> future, Dura
232237

233238
this.timeoutFuture.thenRun(() -> {
234239
if (future.cancel(true) || future.isCompletedExceptionally() || !future.isDone()) {
240+
this.isTimeout = true;
235241
return;
236242
}
237243
try {

0 commit comments

Comments
 (0)