2

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

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

例如,使用 scala 未来,我可以执行以下操作:

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());

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

4

2 回答 2

3

您可以使用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();
        }
        throw (RuntimeException) e; // this is sketchy, handle it differently, maybe by wrapping it in a RuntimeException
    }
    return r;
});

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

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

于 2015-09-11T02:06:34.943 回答
0

请注意, e 将始终是 a java.util.concurrent.CompletionException

CompletableFuture<String> ask = CompletableFuture.supplyAsync(() -> {
    throw new IndexOutOfBoundsException();
});
CompletableFuture<String> translatedException = ask.handle((r, e) -> {
    if (e != null) {
        if (e.getCause() instanceof IndexOutOfBoundsException) {
            throw new IllegalArgumentException();
        }
        throw (RuntimeException) e; // this is sketchy, handle it differently, maybe by wrapping it in a RuntimeException
    }
    return r;
});
于 2021-02-19T09:48:37.903 回答