Reputation: 4562
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?
Upvotes: 3
Views: 3208
Reputation: 4562
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!");
}
}
}
)
);
}
Upvotes: 9
Reputation: 29814
I am not familiar with the Play framework but async
must be returning/using some kind of future. The request is actually performed in a separate Thread which Exceptions are obviously not caught by your try..catch
handler.
There must be some function/method like onComplete
that you can apply to async
allowing you to test the result of running the request.
Upvotes: 2