java - CompletableFuture 吞下异常?

标签 java exception java-8

我一直在玩CompletableFuture,发现一个奇怪的东西。

String url = "http://google.com";

CompletableFuture<String> contentsCF = readPageCF(url);
CompletableFuture<List<String>> linksCF = contentsCF.thenApply(_4_CompletableFutures::getLinks);

linksCF.thenAccept(list -> {
    assertThat(list, not(empty()));
});

linksCF.get();

如果在我的 thenAccept 调用中,断言失败,则不会传播异常。 然后我尝试了一些更丑陋的东西:

linksCF.thenAccept(list -> {
    String a = null;
    System.out.println(a.toString());
});

什么都没有发生,也没有传播异常。我尝试使用 handle 和其他与 CompletableFutures 中的异常相关的方法,但失败了 - 没有一个按预期传播异常。

当我调试 CompletableFuture 时,它确实会捕获如下异常:

final void internalComplete(T v, Throwable ex) {
    if (result == null)
        UNSAFE.compareAndSwapObject
            (this, RESULT, null,
             (ex == null) ? (v == null) ? NIL : v :
             new AltResult((ex instanceof CompletionException) ? ex :
                           new CompletionException(ex)));
    postComplete(); // help out even if not triggered
}

没有别的了。

我使用的是 JDK 1.8.0_05 x64,Windows 7。

我错过了什么吗?

最佳答案

问题是您从不请求接收对 linksCF.thenAccept(..) 的调用结果。

您对 linksCF.get() 的调用将等待您的链中的执行结果。但它只会返回 then linksCF future 的结果。这不包括您的断言结果。

linksCF.thenAccept(..) 将返回一个新的 CompletableFuture 实例。要获取抛出的异常调用 get() 或在新返回的 CompletableFuture 实例上使用 isCompletedExceptionally() 检查异常状态。

CompletableFuture<Void> acceptedCF = linksCF.thenAccept(list -> {
    assertThat(list, not(empty()));
});

acceptedCF.exceptionally(th -> {
    // will be executed when there is an exception.
    System.out.println(th);
    return null;
});
acceptedCF.get(); // will throw ExecutionException once results are available

替代方案?

CompletableFuture<List<String>> appliedCF = linksCF.thenApply(list -> {
    assertThat(list, not(empty()));
    return list;
});

appliedCF.exceptionally(th -> {
    // will be executed when there is an exception.
    System.out.println(th);
    return Coolections.emptyList();
});
appliedCF.get(); // will throw ExecutionException once results are available

关于java - CompletableFuture 吞下异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24183246/

相关文章:

java - 在 Java 8/jsr310 中格式化持续时间

java - 尝试构建一维数组时,推理变量具有不兼容的边界

lambda - 为什么可以在 Thread 类中使用 Lambda 表达式?

java - 基于 Zuul 的路由中的超时异常

java - AlertDialog在DialogFragment中不起作用

java - 从 Android 设备到亚马逊网络服务器 S3 的 HTTP 直播

java - Hibernate注解异常

delphi - 如果列表已排序,为什么 Delphi 的 TStringList.InsertObject() 方法会抛出异常?

java - 获取此异常 : "android.database.sqlite.SQLiteException: no such column: _id: , while compiling" when I have an _id column

java - 我们什么时候应该在方法中抛出异常或捕获异常?