1

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 

Antwort

0

Sogar ich war mit Timeout-Ausnahme in Play 1.2 konfrontiert, da die API lange brauchte, um eine Antwort zurückzusenden. Ich war in der Lage, das Timeout manuell einzustellen, das mein Problem löste.

WSRequest request = WS.url(your_url).timeout("600s"); 
+2

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