什么是简单的方法来添加一些额外的信息到超时异常?假设我有一个这样的代码:
CompletableFuture<ResutType> getSomething()
{
... return someFuture.orTimeout(15, SECONDS);
}
这是我在稍后尝试执行get()
的方法的调用者时获得的所有下游信息:
java.util.concurrent.ExecutionException: java.util.concurrent.TimeoutException
at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:396)
at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2073)
我需要添加更多的信息-哪个操作超时了,超时了多长时间,等等。换句话说,我需要一些异常消息,比如“15秒内超时的东西”,理想情况下使用这样的供应商:
CompletableFuture<ResutType> getSomething()
{
return someFuture.orTimeout(15, SECONDS, () -> new TimeoutException("The Something timed-out in 15s"));
}
4条答案
按热度按时间gwbalxhn1#
您可以使用与
CompletableFuture
的内部超时处理相同的工具:请注意,
isDone()
检查不是严格必要的,因为如果future已经完成,completeExceptionally
就不会执行任何操作。检查只是为了防止在不必要时进行潜在的昂贵的异常构造。这仍然是可能的,但不太可能在isDone()
和completeExceptionally
调用之间完成未来,但没有什么不好的事情会发生,因为completeExceptionally
无论如何都做了正确的事情。你可以像这样测试它
在线试试!
jhdbpxl92#
您可以使用
exceptionallyCompose
(或此方法的任何异步变体):如果你的代码由于
TimeoutException
而失败,你可以通过一个失败的CompletableFuture
返回一个TimeoutException
(或任何其他可抛出的),它有更多的细节。否则,您可以返回导致前一阶段异常完成的同一个throwable。例如,如果
supplyAsync
中有一些RuntimeException
,future.get()
仍然会导致抛出RuntimeException
( Package 在ExecutionException
中)。如果没有例外(即也没有超时),你get()
你的结果正常.有了这些知识,你可以编写自己的
orTimeout
封装器,例如:然后将其用于所有
CompletableFuture
s,如下所示:ecbunoof3#
由于您期望超时,因此考虑将其作为返回类型的一部分,而不是处理
TimeoutException
。一种方法是使用Vavr library的Either
类型将结果类型更改为Either<Timeout, Result>
。一旦future完成并且您获得了它的值,使用
Either
的许多方法之一继续。在最简单的情况下j9per5c44#
天真地说。
当然,你应该更具体地说明例外情况,但我认为这是问题的要点。