我一直在尝试了解在使用 CompletionStage 时如何正确处理异常,我查看了 exceptionly() 方法,但这不足以满足我的需求,我不想用它来拦截由一个异步方法并传递一个新的默认值,我希望它拦截一个异常,可能会破坏链并将链的输出元素的当前类替换为另一个,特别是主方法的输出类。
这是一个示例代码:
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"))));
}
在上面的代码中,如果在 getTabularData 中抛出 SqlException,则异常捕获它并传递一个空列表,因为 getTabularData 的签名是
CompletionStage<List<?>> getTabularData(Map<String, String[]> parameters);
确实,在异常情况下,我可以区分 SqlException 或 NumberFormatException,但最终它必须将 List 传递给 thenApplyAsync,并且一旦流程进入那里,它就无法区分引发了什么异常并返回一个相应的结果不同。
有没有比使用老式的 try catch 块更好的方法来使用 CompletionStage 完成正确的异常处理?
谢谢你,罗伯托