【问题标题】:Handling Exception on Asynchronous Webservice Request处理异步 Web 服务请求的异常
【发布时间】:2013-03-14 13:50:53
【问题描述】:

使用 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!");
    }
}

当我尝试请求 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!");
    }
}

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

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

Execution Exception 
[TimeoutException: No response received after 1000] 

谁能解释一下为什么无法使用我上面的代码捕获 WS 请求的异常?使用 Play!Framework WS 库处理异常的最佳方法是什么?

【问题讨论】:

    标签: java playframework playframework-2.1


    【解决方案1】:

    为了处理 异步 请求(例如使用 Play!Framework 2.1.0 的 WS 请求)发生的异常,Promise 上有一个名为 recover(F.Function&lt;java.lang.Throwable,A&gt; 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!");
                        }
                    }
                }
            )
        );
    }
    

    【讨论】:

    • 上面的TimeoutException应该是F.PromiseTimeoutException吗?
    【解决方案2】:

    我不熟悉 Play 框架,但 async 一定会返回/使用某种未来。该请求实际上是在一个单独的线程中执行的,您的try..catch 处理程序显然没有捕获到异常。

    必须有一些类似onComplete 的函数/方法可以应用到async,以便测试运行请求的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-23
      • 1970-01-01
      • 2019-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多