Wie kann ich Timeout-Ausnahme in Play ws Client behandeln? Wenn ich RequestTimeout
und Prozessstream angeben, wird CompletionStage
erfolgreich beendet, obwohl eine Ausnahme vorliegt.Play Framework-Anforderungs-Timeout
Siehe unten für ein Beispiel.
-Code (aus here):
// Make the request, which should timeout
CompletionStage<StreamedResponse> futureResponse = ws.url("https://download.docker.com/mac/stable/Docker.dmg")
.setMethod("GET").setRequestTimeout(1000)
.stream();
CompletionStage<Long> bytesReturned = futureResponse.thenCompose(res -> {
Source<ByteString, ?> responseBody = res.getBody();
// Count the number of bytes returned
Sink<ByteString, CompletionStage<Long>> bytesSum = Sink.fold(0L, (total, bytes) ->
{
long len = bytes.toArray().length;
return total + len;
});
return responseBody.runWith(bytesSum, materializer);
}).handle((res, err) -> {
LOGGER.info("Res = {}, err = {}", res, err);
return 200L;
}).exceptionally(ex -> {
LOGGER.error("See exception");
return 100L;
});
try {
bytesReturned.toCompletableFuture().get();
LOGGER.info("Got response");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
LOGGER.error("Step completed");
Ich sehe in Protokollen, die java.util.concurrent.TimeoutException
und o.a.netty.timeout.TimeoutTimerTask
geworfen werden, aber futureResponse
erfolgreich abgeschlossen. Gibt es eine Möglichkeit, diesen Fehler zu finden?
Mein Problem ist, dass ich versuche, diese Antwort an den Benutzer durch Controller zurückgeben, und das hängt einfach, weil nicht alle Daten übertragen wurden.
[debug] i.n.u.i.JavassistTypeParameterMatcherGenerator - Generated: io.netty.util.internal.__matchers__.org.asynchttpclient.HttpResponseBodyPartMatcher
[debug] o.a.netty.channel.DefaultChannelPool - Closed 0 connections out of 0 in 0 ms
[debug] o.a.netty.timeout.TimeoutTimerTask - Request timeout to download.docker.com/52.84.239.124:443 after 1000 ms for NettyResponseFuture{currentRetry=0,
isDone=0,
isCancelled=0,
asyncHa[email protected]376665d1,
[email protected]9d4d,
[email protected][Not completed],
uri=https://download.docker.com/mac/stable/Docker.dmg,
keepAlive=true,
redirectCount=0,
[email protected]789c9776,
inAuth=0,
statusReceived=1,
touch=1491606083196} after 1075 ms
[debug] o.a.netty.channel.ChannelManager - Closing Channel [id: 0x66ec6bbd, L:/10.155.124.116:52337 - R:download.docker.com/52.84.239.124:443]
[debug] o.a.netty.request.NettyRequestSender - Aborting Future NettyResponseFuture{currentRetry=0,
isDone=0,
isCancelled=0,
asyncHa[email protected]376665d1,
[email protected]9d4d,
[email protected][Not completed],
uri=https://download.docker.com/mac/stable/Docker.dmg,
keepAlive=true,
redirectCount=0,
[email protected]789c9776,
inAuth=0,
statusReceived=1,
touch=1491606083196}
[debug] o.a.netty.request.NettyRequestSender - Request timeout to download.docker.com/52.84.239.124:443 after 1000 ms
java.util.concurrent.TimeoutException: Request timeout to download.docker.com/52.84.239.124:443 after 1000 ms
at org.asynchttpclient.netty.timeout.TimeoutTimerTask.expire(TimeoutTimerTask.java:43)
at org.asynchttpclient.netty.timeout.RequestTimeoutTimerTask.run(RequestTimeoutTimerTask.java:48)
at io.netty.util.HashedWheelTimer$HashedWheelTimeout.expire(HashedWheelTimer.java:588)
at io.netty.util.HashedWheelTimer$HashedWheelBucket.expireTimeouts(HashedWheelTimer.java:662)
at io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:385)
at java.lang.Thread.run(Thread.java:745)
[debug] o.a.netty.handler.HttpHandler - Channel Closed: [id: 0x66ec6bbd, L:/10.155.124.116:52337 ! R:download.docker.com/52.84.239.124:443] with attribute INSTANCE
[info] controllers.RedirectController - Res = 2556824, err = null
[info] controllers.RedirectController - Got response
[error] controllers.RedirectController - Step completed
Ich erinnere mich nicht Details, aber das funktioniert nicht. Ich habe dort alle möglichen Timeouts eingestellt, aber Ausnahmen werden auf der unteren Ebene stattfinden, und ich konnte das nicht abfangen. Ich beendete den Apache Async Http Client, den ich direkt anrief. Es gibt eine Möglichkeit, Exception-Handler dort zu überschreiben. – Tigran