Handling Exception on Asynchronous Webservice Request

java, playframework, playframework-2.1

Solution

To handle exception that occur on asynchronous request such as `WS` request with Play!Framework 2.1.0, there is method on `Promise` named `recover(F.Function<java.lang.Throwable,A> function)`.

The method should be called when we want to handle all exception occured while requesting using `WS` library. So, I solved the problem using code that looked like following:

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

Problem

I am still new to implement web service request using Play!Framework 2.1 WS library. Now, I have problem on understanding the WS library behaviour. Firstly, I have code like this : ``` 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!"); } } ``` When I try to request the `espnRss` action, I got SUCCESS response. Then, I want to set WS timeout on the request. So, I changed my previous code like this : ``` 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!"); } } ``` My internet connection is not fast (Download speed is about 40 KB/s) and I do that on purpose (set request time out for 1 second) to make exception handling code is executed. But, I get default response from framework, not `internalServerError` response the code provided. ``` Execution Exception [TimeoutException: No response received after 1000] ``` Can anyone explain me why the exception on WS request cannot be caught using my code above? How is the best way to handle exception using Play!Framework WS library?

Original source