Java net HttpClient: React to timeout in async call

1k Views Asked by At

My goal is to react to the timeout in an asyncronius call of the HttpClient. I find many information on how to set the different timeouts but I do not find any information on how to react to the timeout if it occures.

The documentaton stating that:

If the response is not received within the specified timeout then an HttpTimeoutException is thrown from HttpClient::send or HttpClient::sendAsync completes exceptionally with an HttpTimeoutException

But I don't know what exacly completes exceptionally mean.

Example

In a sync call I can do (If the server behind the test URL don't answer):

HttpRequest request = HttpRequest.newBuilder()
                                 .uri(new URI("http://localhost:8080/api/ping/public"))
                                 .timeout(Duration.ofSeconds(2))
                                 .build();
HttpClient client = HttpClient.newBuilder().build();

try {
  client.send(request, HttpResponse.BodyHandlers.ofInputStream());
} catch (HttpTimeoutException e) {
  System.out.println("Timeout");
}

What I want now is to do the same reaction to an async call like:

HttpRequest request = HttpRequest.newBuilder()
                                 .uri(new URI("http://localhost:8080/api/ping/public"))
                                  .timeout(Duration.ofSeconds(2))
                                  .build();
HttpClient client = HttpClient.newBuilder().build();

client.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream()).thenIfTimeout(System.out.println());

The last call is only a placeholder for the reaction to the timeout and does not exists. But how can I archive this?

1

There are 1 best solutions below

0
On BEST ANSWER

Depending on what you are trying to do, there are at least three methods that you could use to take action when an exception occurs:

  1. CompletableFuture.exceptionally
  2. CompletableFuture.whenComplete
  3. CompletableFuture.handle
  • 1 allows you to return a result of the same type when an exception occurs
  • 2 allows you to trigger some action - and doesn't change the completion result or exception.
  • 3 allows you to trigger some action, and change the type of the completion result or exception

By far the easiest would be to use 2. Something like:

client.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream())
      .whenComplete((r,x) -> {
            if (x instanceof HttpTimeoutException) {
                 // do something
            }
       });