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?