繁体   English   中英

如何从CompletableFuture抛出自定义异常?

[英]How to throw a custom exception from CompletableFuture?

问题:如何直接从.exceptionally()抛出自定义异常?

List<CompletableFuture<Object>> futures =
    tasks.stream()
        .map(task -> CompletableFuture.supplyAsync(() -> businessLogic(task))
        .exceptionally(ex -> {
                if (ex instanceof BusinessException) return null;

                //TODO how to throw a custom exception here??
                throw new BadRequestException("at least one async task had an exception");
        }))
        .collect(Collectors.toList());

try {
    List<Object> results = futures.stream()
        .map(CompletableFuture::join)
        .collect(Collectors.toList());
} catch (CompletionException e) {
        if (e.getCause() instanceof RuntimeException) {
              throw (RuntimeException) e.getCause();
        }
        throw new RuntimeException(e.getCause());
}

问题:我总是得到一个CompletionExceptionex.getCause()BadRequestException instanceof。

这有可能吗?

正如Didier L所说,函数抛出的异常(或者通常是完成 CompletableFuture 异常 )总是包含在CompletionException (除非它们已经是CompletionExceptionCancellationException )。

但请注意,甚至在尝试通过exceptionally转换异常时,您的代码变得更加简单:

List<CompletableFuture<Object>> futures =
    tasks.stream()
        .map(task -> CompletableFuture.supplyAsync(() -> businessLogic(task)))
        .collect(Collectors.toList());
try {
    List<Object> results = futures.stream()
        .map(CompletableFuture::join)
        .collect(Collectors.toList());
} catch (CompletionException e) {
    throw e.getCause() instanceof BusinessException?
        new BadRequestException("at least one async task had an exception"): e;
}

要么

… catch (CompletionException e) {
    throw e.getCause() instanceof BusinessException?
        new BadRequestException("at least one async task had an exception"):
        e.getCause() instanceof BusinessException? (RuntimeException)e.getCause(): e;
}

由于exceptionally的主要目的是将异常转换为非异常结果值,因此使用它将异常转换为另一个抛出的异常并不是最合适的,它还需要一个instanceof 因此,在catch子句中执行此转换将使您免于另一个转换步骤。

这是不可能的。 join()Javadoc明确指出:

完成后返回结果值,如果异常完成则抛出(未经检查的)异常。 为了更好地符合常用函数形式的使用, 如果完成此CompletableFuture所涉及的计算引发异常,则此方法将抛出(未经检查的) CompletionException ,并将基础异常作为其原因。

(重点是我的)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM