2013-03-14 138 views
3

我还是新来实现使用Play!Framework 2.1 WS库的Web服务请求。现在,我在理解WS库行为方面存在问题。异步Web服务请求的处理异常

首先,我有这样的代码:

public static Result espnRss() { 
    try { 
     // do request 
     return async(
      WS.url("http://espnfc.com/rss/news?section=premierleague").get().map(
       new F.Function<WS.Response, Result>() { 
        @Override 
        public Result apply(WS.Response response) throws Throwable { 
         return ok("Success!"); // success request 
        } 
       } 
      ) 
     ); 
    } catch (Exception e) { 
     // exception occured 
     return internalServerError("Oops, connect exception occured!"); 
    } 
} 

当我尝试要求espnRss动作,我得到了成功响应。

然后,我想在请求上设置WS超时。于是,我改变了我以前像这样的代码:

public static Result espnRss() { 
    try { 
     // set request timeout for 1000 ms and do request 
     return async(
      WS.url("http://espnfc.com/rss/news?section=premierleague").setTimeout(1000).get().map(
       ... // same as previous 
      ) 
     ); 
    } catch (Exception e) { 
     // exception occured 
     return internalServerError("Oops, connect exception occured!"); 
    } 
} 

我的互联网连接并不快(下载速度约为40 KB/s)和我这样做是故意(set请求1秒超时),使异常处理代码被执行。

但是,我得到框架的默认响应,而不是internalServerError响应提供的代码。

Execution Exception 
[TimeoutException: No response received after 1000] 

任何人都可以解释为什么WS请求上的异常不能用上面的代码捕获吗?使用Play!Framework WS库处理异常的最佳方法是什么?

回答

9

来处理异步请求,如要求WS与播放!框架2.1.0发生异常,对Promise方法命名recover(F.Function<java.lang.Throwable,A> function)

当我们想要处理在请求使用WS库时处理所有异常时应该调用该方法。所以,我使用如下代码解决了问题:

public static Result espnRss() { 
    // do request 
    return async(
     WS.url("http://espnfc.com/rss/news?section=premierleague").setTimeout(100).get().map(
      new F.Function<WS.Response, Result>() { 
       @Override 
       public Result apply(WS.Response response) throws Throwable { 
        return ok("Success!"); // success request 
       } 
      } 
     ).recover(// to handle error occured on redeemed PROMISE 
      new F.Function<Throwable, Result>() { 
       @Override 
       public Result apply(Throwable throwable) throws Throwable { 
        // option to distinguish exception 
        if (throwable instanceof TimeoutException) { 
         return internalServerError("Oops, time out exception occured!"); 
        } else { 
         return internalServerError("Oops, other exception occured!"); 
        } 
       } 
      } 
     ) 
    ); 
} 
+0

上面的'TimeoutException'是否应该是'F.PromiseTimeoutException'? – RamV13 2016-04-16 04:01:08

2

我不熟悉Play框架,但async必须返回/使用某种未来。该请求实际上是在单独的线程中执行的,该例外显然不会被您的try..catch处理程序捕获。

必须有一些功能/方法,如onComplete,您可以应用async允许您测试运行请求的结果。

+0

+1感谢提示。我会尝试进行研究......;) – 2013-03-22 02:54:54