将未来可完成的异常映射到不同的异常类型?

dev*_*rts 5 java exception completable-future

我正在使用 java 8 的可完成的 future,我希望能够接受 future 抛出的异常并将其转换为不同的异常。

一旦发生异常,我尝试过的所有复合材料似乎都会短路。

例如,使用 scala future,我可以做这样的事情:

scala.concurrent.Future<Object> translatedException = ask.recover(new Recover<Object>() {
            @Override public Object recover(final Throwable failure) throws Throwable {
                if (failure instanceof AskTimeoutException) {
                    throw new ApiException(failure);
                }

                throw failure;
            }
        }, actorSystem.dispatcher());
Run Code Online (Sandbox Code Playgroud)

我希望能够在未来的 java 复合块中模仿这一点。这可能吗?

Sot*_*lis 4

您可以使用CompletableFuture#handle(BiFunction)。例如

CompletableFuture<String> ask = CompletableFuture.supplyAsync(() -> {
    throw new IndexOutOfBoundsException();
});
CompletableFuture<String> translatedException = ask.handle((r, e) -> {
    if (e != null) {
        if (e instanceof IndexOutOfBoundsException) {
            throw new IllegalArgumentException();
        }
        // fallback
        if (e instanceof RuntimeException) {
            throw (RuntimeException) e;
        }
        throw new RuntimeException(e);
    }
    return r;
});
Run Code Online (Sandbox Code Playgroud)

如果ask以异常完成,则将translatedException以可能转换的异常完成。否则,它将具有相同的成功结果值。

关于我在代码中的注释,该handle方法期望未声明BiFunctionapply方法的方法抛出Throwable. 因此,lambda 主体本身不能抛出Throwable. 该参数e是类型的Throwable,因此您不能throw直接使用它。如果您知道它是那种类型,则可以将其转换为RuntimeException,或者可以将其包装在 aRuntimeExceptionthrowthat 中。