Java 8 CompletionStage和异常处理
我一直在试图理解在使用CompletionStage时如何正确处理异常,我已经研究了exception()方法,但这还不足以满足我的需要,我不想用它截获异步方法引发的异常并传递新的默认值,我希望它截获异常,可能会断开该链,并用另一个类替换该链的输出元素的当前类,特别是main方法的输出类 这是一个示例代码:Java 8 CompletionStage和异常处理,java-8,completion-stage,Java 8,Completion Stage,我一直在试图理解在使用CompletionStage时如何正确处理异常,我已经研究了exception()方法,但这还不足以满足我的需要,我不想用它截获异步方法引发的异常并传递新的默认值,我希望它截获异常,可能会断开该链,并用另一个类替换该链的输出元素的当前类,特别是main方法的输出类 这是一个示例代码: public CompletionStage<Result> getTableAsJSON(String instance, Http.Request request) {
public CompletionStage<Result> getTableAsJSON(String instance, Http.Request request) {
return this.repositoryManager.getRepository(instance).map(repo ->
repo.getTabularData(request.queryString()).exceptionally(ex -> {
return new ArrayList<>();
}).thenApplyAsync(list -> {
if(!list.isEmpty())
return ok(toJson(list));
else
return notFound(this.messagesApi.preferred(request).at("noDataFound"));
}, this.httpExecutionContext.current()
) ).orElse(CompletableFuture.completedFuture(notFound(this.messagesApi.preferred(request).at("instanceNotFound"))));
}
公共CompletionStage getTableAsJSON(字符串实例,Http.Request){
返回此.repositoryManager.getRepository(instance).map(repo->
repo.getTabularData(request.queryString())。异常(ex->{
返回新的ArrayList();
}).ThenApplySync(列表->{
如果(!list.isEmpty())
返回ok(toJson(list));
其他的
returnnotfound(this.messagesApi.preferred(request.at)(“noDataFound”);
},this.httpExecutionContext.current()
)).orElse(CompletableFuture.completedFuture(notFound(this.messagesApi.preferred(request.at)(“instancentfound”)));
}
在上面的代码中,如果在getTabularData中抛出SqlException,则异常地捕获它并传递一个空列表,因为getTabularData的签名是
CompletionStage<List<?>> getTabularData(Map<String, String[]> parameters);
completionstage不能将异常替换为空的ArrayList
。我们无法告诉您该怎么做,因为您没有说明如何处理异常。如果您想让getTableAsJSON
的调用者处理异常情况,只需删除.excellective(ex->{return new ArrayList();})
,而无需任何替换。基本上,我需要这样做:public CompletionStage。。。{返回this.repositoryManager.getRepository(instance).map(repo->repo.getTabularData(request.queryString())。异常情况下(例如->{返回实例或结果(假设内部服务器错误结果)})。然后应用同步(list->{if(!list.isEmpty())return ok;else return notFound error;},this.httpExecutionContext.current())}只需使用repo.getTabularData(…)。然后使用applyasync(list->/*进程列表*/)。异常情况下(ex->/*返回错误结果*/)
我想在这个例子中,我可以简单地交换应用和例外的顺序,因为链中只有一个链接,但是如果我说的是更复杂的合成和应用链,那么在最后添加例外可能是不够的。假设链中的一个链接抛出了一个吸引,我可以想象的场景中,我想检查什么是Exchange是,并打破链,并立即返回结果,或处理异常,并转发默认值以下,然后应用。我想这不可能。我看不出有什么问题。您可以在任何可能映射到合理默认值的地方插入。否则,链在末端异常地。不需要“断开链”,当发生异常时,所有后续阶段都将被跳过(如果这些阶段没有输入,那么它将如何工作?)。在异常情况下不被跳过的唯一阶段是handle[Async]
,whenComplete[Async]
,以及异常代码>。只是不要将异常替换为空的ArrayList
。我们无法告诉您该怎么做,因为您没有说明如何处理异常。如果您想让getTableAsJSON
的调用者处理异常情况,只需删除.excellective(ex->{return new ArrayList();})
,而无需任何替换。基本上,我需要这样做:public CompletionStage。。。{返回this.repositoryManager.getRepository(instance).map(repo->repo.getTabularData(request.queryString())。异常情况下(例如->{返回实例或结果(假设内部服务器错误结果)})。然后应用同步(list->{if(!list.isEmpty())return ok;else return notFound error;},this.httpExecutionContext.current())}只需使用repo.getTabularData(…)。然后使用applyasync(list->/*进程列表*/)。异常情况下(ex->/*返回错误结果*/)
我想在这个例子中,我可以简单地交换应用和例外的顺序,因为链中只有一个链接,但是如果我说的是更复杂的合成和应用链,那么在最后添加例外可能是不够的。假设链中的一个链接抛出了一个吸引,我可以想象的场景中,我想检查什么是Exchange是,并打破链,并立即返回结果,或处理异常,并转发默认值以下,然后应用。我想这不可能。我看不出有什么问题。您可以在任何可能映射到合理默认值的地方插入。否则,链在末端异常地。不需要“断开链”,当发生异常时,所有后续阶段都将被跳过(如果这些阶段没有输入,那么它将如何工作?)。在异常情况下不被跳过的唯一阶段是handle[Async]
,whenComplete[Async]
,以及异常代码>。