我在一些代码周围有一个番石榴重试器:
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
.retryIfExceptionOfType(Exception.class)
.withStopStrategy(MoreStopStrategies.liveStopAfterAttempt(retries))
.withWaitStrategy(MoreWaitStrategies.liveExponentialWait(TimeUnit.MILLISECONDS, retrySleep, TimeUnit.MILLISECONDS))
.build();
try {
retryer.call(() -> {
return doStuff();
});
} catch (ExecutionException | RetryException e) {
throw Throwables.propagate(e);
}
让我们说doStuff()
抛出一个ArithmeticException
。我如何在retryer.call()
之外捕获它?
因此,重试程序将尝试几次,失败并进入catch (ExecutionException | RetryException e)
块。我如何检索里面的ArithmeticException
?
谢谢!
答案 0 :(得分:1)
这是一个有点错误的模式。你说任何异常都可以重试。然后ArithmeticException
可以重试。这不是你想要的。
这是重试的实施方式。请注意第二行的注释。
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
// .retryIfExceptionOfType(Exception.class)
.withStopStrategy(MoreStopStrategies.liveStopAfterAttempt(retries))
.withWaitStrategy(MoreWaitStrategies.liveExponentialWait(TimeUnit.MILLISECONDS, retrySleep, TimeUnit.MILLISECONDS))
.build();
void doStuff() {
try {
retryer.call(() -> {
doRealStuff();
});
} catch (RetryException e) {
throw new RuntimeException("Call never succeeded", e);
} catch (ExecutionException e) {
Throwables.propagateIfPossible(e.getCause(), ArithmeticException.class);
throw new RuntimeException("Unexpected", e);
}
}
然后当您实际致电doStuff
时:
try {
doStuff();
} catch(ArithmeticException e) {
System.err.println("Arithmetic exception caught:");
e.printStackTrace(System.err);
}
答案 1 :(得分:0)
如果没有看到你的doStuff()
或者至少知道它会引发什么样的例外,那就很难回答。
一般情况下,如果您Retryer
认为每个Exception
都不成功,它会重试并最终停止 - 但它会抓住任何 Throwable
执行代码(见Retryer code,第162行)
解决方案是:
doStuff()
仅在导致停止重试的情况下抛出ArithmeticException
,并且另一种异常标记为需要重试,则可以执行retryIfExceptoinOfType(OtherException.class)
。然后,根据文档the docs <强>抛出:强>
中
java.util.concurrent.ExecutionException
- 如果给定的callable抛出异常,并且拒绝谓词认为该尝试成功。原始异常包含在ExecutionException
。
call()
将抛出一个ExecutionException
,你可以在Retryer之外捕获并检查包装的异常。
ArithmeticExcpetion
全部doStuff()
将抛出,并且这也表示重试者应该重试,那么您可以编写一个自定义StopStrategy
,它会抛出ArithmeticExpcetion
,它在Retryer中无处可寻。但是我建议你完成重写你的代码,你的数据流似乎有点破碎。如果预期ArithmeticExpcetion
(或实际上甚至是任何异常,在retryIf中指定Exception.class
),则 也不应该意外,需要特殊处理。