如何抽象捕获异常 CompletableFutures 以调用方法

How to abstract catching exceptions CompletableFutures for invoking a method

好的,我有这样的方法

  1. CompletableFuture fetchCar(int id);
  2. CompletableFuture runSomething(Something t, Extra d);
  3. CompletableFuture 调用();

我想要一个我可以使用的方法来执行以下操作,以便它转换任何同步异常以在将来放置

private CompletableFuture<Void> invokeSomething(Something something) {
    CompletableFuture<Void> future;
    try {
        future = something.runSomething(t, d);
    } catch(Throwable e) {
        future = new CompletableFuture<Void>();
        future.completeExceptionally(e);
    }

    return future;
}

请注意,我只是碰巧选择了 #2 作为示例,但我想将它设为通用的,这样我就可以停止输入它,因为通常它需要偶尔完成一次,以确保您处理同步和异步异常相同。

我不确定这是否是您要查找的内容,但您可以创建一个实用函数:

public static <T> CompletableFuture<T> foo(Callable<CompletableFuture<T>> callable) {
    try {
        return callable.call();
    } catch (Exception ex) {
        return CompletableFuture.failedFuture(ex);
    }
}

然后您可以像这样使用它:

Something something = ...;
CompletableFuture<Void> future = foo(() -> invokeSomthing(something));

一些注意事项:

  1. 使用 Callable 因为它的函数方法 call 可以抛出 Exception。如果使用 Supplier 之类的东西,那么将它与可以抛出已检查异常的方法一起使用会很麻烦。
  2. 使用 catch (Exception ex) 而不是 catch (Throwable ex) 因为 Callable#call 不会抛出 Throwable 并且捕获 Error 通常被认为是不好的做法。如果需要,您可以随时将其更改为 Throwable
  3. 如果 callablenull,此实用程序方法将 return 由 NPE 引起的未来失败;不知道是否需要。