处理异步Web服务请求的异常

Way*_*oga 3 java playframework playframework-2.1

我仍然是使用Play!Framework 2.1 WS库实现Web服务请求的新手.现在,我在理解WS库行为方面存在问题.

首先,我有这样的代码:

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!");
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试请求espnRss操作时,我获得了SUCCESS响应.

然后,我想在请求上设置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!");
    }
}
Run Code Online (Sandbox Code Playgroud)

我的互联网连接速度不快(下载速度约为40 KB/s),我故意这样做(设置请求超时1秒),以便执行异常处理代码.

但是,我从框架获得默认响应,而不是internalServerError响应提供的代码.

Execution Exception 
[TimeoutException: No response received after 1000] 
Run Code Online (Sandbox Code Playgroud)

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

Way*_*oga 9

要处理异步请求上发生的异常,例如WS使用Play!Framework 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!");
                    }
                }
            }
        )
    );
}
Run Code Online (Sandbox Code Playgroud)