重新抛出exceptionally
内部异常似乎不允许使用CompletionStage方法。Java 8 CompletionStage异常重新抛出异常
我需要检查某一种异常的,如果没有我需要把它重新抛出回:
Future<JsonNode> futureSite = someClient.getSite(siteId, queryParams);
CompletionStage<JsonNode> outcome = FutureConverters.toJava(futureSite);
return outcome.thenApplyAsync((siteJson) -> {
Site site = Json.fromJson(siteJson, Site.class);
try {
return function.apply(site);
} catch (RequestException e) {
return e.result;
}
}, httpExecutionContext.current()).exceptionally(throwable -> {
if(throwable instanceof SomeClientException) {
if(((SomeClientException) throwable).httpStatusCode == 404) {
return entityNotFound("Site", siteId);
}
}
// let JSON parsing failures and other errors bubble up, TODO play2.5
throw throwable;
});
throw throwable
错误出来说unhandledException java.lang.Throwable
什么接口将可能允许重新抛出回异常?还是有更好的办法?
更新:
我试图从霍尔格如下建议,但我仍然不知道在什么时候,我其实可以再次抛出这样的:
BaseController.java :
protected class RequestException extends Exception {
private static final long serialVersionUID = -2154871100650903869L;
public Result result;
public RequestException(Result result) {
this.result = result;
}
}
@FunctionalInterface
protected interface RequestFunction<T, R> {
R apply(T t) throws RequestException;
}
protected CompletionStage<Result> performWithSite(final Long siteId, RequestFunction<Site, Result> function) {
QueryParams queryParams = QueryParams.create();
Future<JsonNode> futureSite = someClient.getSite(siteId, queryParams);
CompletionStage<JsonNode> outcome = FutureConverters.toJava(futureSite);
return handleSpecific(
outcome.thenApplyAsync(siteJson -> {
Site site = Json.fromJson(siteJson, Site.class);
try {
return function.apply(site);
} catch (RequestException e) {
return e.result;
}
}, httpExecutionContext.current()),
throwable -> throwable instanceof SomeClientException
&& ((SomeClientException)throwable).httpStatusCode == 404,
() -> entityNotFound("Site", siteId));
}
protected Result entityNotFound(String entityName, String id) {
// building our custom error model.
Error e = new Error(
Http.Status.NOT_FOUND,
ErrorCode.ENTITY_NOT_FOUND,
ErrorCodes.NOT_FOUND, new String[]{entityName, id});
return notFound(e.asJson());
}
所以,上面的代码的本质是我需要联系某个客户端来检查该站点是否存在,并且客户端可以抛出SomeClientException异常。
Controller.java
public Result destroy(Long siteId, Long productId){
return performWithSite(siteId, site -> {
productWriter.deleteProduct(siteId, productId);
return noContent();
}).toCompletableFuture().exceptionally(e -> {
Logger.error(e+"exception");
throw e.getCause();
// above line errors out as unhandledException java.lang.throwable, I need the NotFoundException which is contained within the CompletionException to be thrown.
});
}
//在上面的控制器代码,我做的远程调用后,客户端检查站点存在,我需要继续前进,删除产品。
productWriter.deleteProduct(siteId, productId)
可能仍然抛出NotFoundException
或别的东西,我需要重新抛出回来...... 使从控制器代码重新抛出的异常是在调用链拿起我们的自定义异常处理程序。
这里是我的测试案例:
"return 404 when deleting a nonexistent Product" {
when(productDAO.findBySiteAndProductId(anyLong(), anyLong())) thenReturn null
a[NotFoundException] should be thrownBy { controller.destroy(0L, 1L) }
}
我认为这个问题不是特定游戏 –