PlayWS - How to throw an exception when Request Timeout is reached?

When performing long downloads with PlayWS, which uses CompletableFuture, these sometimes reach the defined request timeout. When that happens, then PlayWS doesn't seem to throw an exception (at least in my configuration), so the download can't be marked as failed and is processed although the data is corrupt.

Please excuse this abomination of code:

final CompletionStage<WSResponse> futureResponse = this.playWS.client
        .url(importSource.getDownloadUrl())
        .setMethod(HttpMethod.GET)
        .setRequestTimeout(Duration.ofSeconds(5)) // When the timeout is reached, the download gets canceled
        .stream();

try {
    futureResponse
            .thenAccept(res -> {
                try (OutputStream outputStream = Files.newOutputStream(file.toPath())) {
                    final Source<ByteString, ?> responseBody = res.getBodyAsSource();
                    final Sink<ByteString, CompletionStage<Done>> outputWriter =
                            Sink.foreach(bytes -> {
                                outputStream.write(bytes.toArray());
                            });
                    responseBody
                            .runWith(outputWriter, this.playWS.materializer)
                            .whenComplete((value, error) -> {
                                System.out.println("VALUE: "+value); // == "Done"
                                System.out.println("Error: "+error); // == null
                            })
                            .exceptionally(exception -> {
                                throw new IllegalStateException("Download failed for: " + importSource.getDownloadUrl(), exception);
                            })
                            .toCompletableFuture().join();
                } catch (final IOException e) {
                    throw new IllegalStateException("Couldn't open or write to OutputStream.", e);
                }
            })
            .exceptionally(exception -> {
                throw new IllegalStateException("Download failed for: " + importSource.getDownloadUrl(), exception);
            })
            .toCompletableFuture().get();
} catch (InterruptedException | ExecutionException e) {
    throw new IllegalStateException("Couldn't complete CompletableFuture.", e);
}

Am I doing something fundamentally wrong or is this a bug?

The only solutions I see are:

  1. Count the received bytes and compare them to the Content-Length header.
  2. Set the request timeout to -1 (indefinite).

Thanks for any suggestion.