Java 8 CompletionStage和异常处理

Java 8 CompletionStage和异常处理,java-8,completion-stage,Java 8,Completion Stage,我一直在试图理解在使用CompletionStage时如何正确处理异常,我已经研究了exception()方法,但这还不足以满足我的需要,我不想用它截获异步方法引发的异常并传递新的默认值,我希望它截获异常,可能会断开该链,并用另一个类替换该链的输出元素的当前类,特别是main方法的输出类 这是一个示例代码: public CompletionStage<Result> getTableAsJSON(String instance, Http.Request request) {

我一直在试图理解在使用CompletionStage时如何正确处理异常,我已经研究了exception()方法,但这还不足以满足我的需要,我不想用它截获异步方法引发的异常并传递新的默认值,我希望它截获异常,可能会断开该链,并用另一个类替换该链的输出元素的当前类,特别是main方法的输出类

这是一个示例代码:

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]
,以及
异常​