2013-03-14 117 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