来自CompletableFuture的抛出异常

我有以下代码:

// How to throw the ServerException?

public void myFunc() throws ServerException{

// Some code

CompletableFuture<A> a = CompletableFuture.supplyAsync(() -> {

try {

return someObj.someFunc();

} catch(ServerException ex) {

// throw ex; gives an error here.

}

}));

// Some code

}

someFunc()抛出一个ServerException。我不想在这里处理此问题,但是将异常从抛出someFunc()给的调用者myFunc()

回答:

您的代码建议您稍后以相同的方法使用异步操作的结果,因此CompletionException无论如何都必须进行处理,因此一种处理方法是

public void myFunc() throws ServerException {

// Some code

CompletableFuture<A> a = CompletableFuture.supplyAsync(() -> {

try { return someObj.someFunc(); }

catch(ServerException ex) { throw new CompletionException(ex); }

});

// Some code running in parallel to someFunc()

A resultOfA;

try {

resultOfA = a.join();

}

catch(CompletionException ex) {

try {

throw ex.getCause();

}

catch(Error|RuntimeException|ServerException possible) {

throw possible;

}

catch(Throwable impossible) {

throw new AssertionError(impossible);

}

}

// some code using resultOfA

}

在的异步处理中抛出的所有异常Supplier都将CompletionException在调用时包装为一个join,除了ServerException我们已经包装在一个CompletionException

当重新引发的原因时CompletionException,我们可能会遇到未检查的异常,即Erroror的子类RuntimeException或我们的自定义检查的异常ServerException。上面的代码通过多次捕获来处理所有这些错误,然后将它们重新抛出。由于声明的返回类型getCause()Throwable,尽管我们已经处理了所有可能的类型,但编译器仍要求我们处理该类型。直接的解决方案是将包裹在包装中的这个实际上不可能的可抛物抛出AssertionError

或者,我们可以为自定义异常使用将来的替代结果:

public void myFunc() throws ServerException {

// Some code

CompletableFuture<ServerException> exception = new CompletableFuture<>();

CompletableFuture<A> a = CompletableFuture.supplyAsync(() -> {

try { return someObj.someFunc(); }

catch(ServerException ex) {

exception.complete(ex);

throw new CompletionException(ex);

}

});

// Some code running in parallel to someFunc()

A resultOfA;

try {

resultOfA = a.join();

}

catch(CompletionException ex) {

if(exception.isDone()) throw exception.join();

throw ex;

}

// some code using resultOfA

}

该解决方案将所有“意外”的可扔物以它们的包装形式重新抛出,但仅将自定义ServerExceptionexception将来通过的原始形式抛出。请注意,在查询未来之前,我们必须确保a已完成操作(例如join()先调用)exception,以避免出现竞争情况。

以上是 来自CompletableFuture的抛出异常 的全部内容, 来源链接: utcz.com/qa/429789.html

回到顶部