private String stringResult=null;
private Throwable throwableResult=null;
@Test
public void whereIsTheThrowable() {
Observable.just("foo")
.map(this::justBlowUp)
.retryWhen(errors -> errors.zipWith(Observable.range(1, 3), (n, i) -> i))
.subscribe(s -> stringResult=s, throwable -> throwableResult=throwable);
assertNull(stringResult);
assertNotNull(throwableResult);
}
private String justBlowUp(String s) {
throw new RuntimeException();
}
该测试在 RxJava 2.1.7 中失败。 retryWhen()
似乎消耗了 Throwable
,即使它不再重试。 subscribe()
lambda 没有得到任何 Throwable
.虽然这个测试很愚蠢(justBlowUp()
会爆炸),但您可以想象一个 Observable
工作通常成功的链,只是偶尔失败,而且很少连续失败四次。但是,在那种情况下,拥有 Throwable
会很有用。用于记录目的。
retryUntil()
允许 subscribe()
得到最后的Throwable
... 但随后在 retryUntil()
我们没有 Throwable
根本无法对其做出决定(例如,如果它似乎是 Internet 连接错误,则重试 N 次,但对于其他一切都快速失败)。 retryWhen()
似乎是更强大的选项,但我们如何获得最终的 Throwable
, 在 retryWhen()
之后停止重试?
我可以使用一个字段来保存 Throwable
, 设置在 retryWhen()
内逻辑,但感觉应该有一个更惯用的解决方案。
最佳答案
retryWhen
将处理程序的完成视为正常完成的指示器,因此,处理程序应该在重试选项用尽后失败:
Observable.just("foo")
.map(this::justBlowUp)
.retryWhen(errors -> errors.flatMap(new Function<Throwable, Observable<Integer>>() {
int count;
@Override
public Observable<Integer> apply(Throwable error) {
if (count++ < 3) {
return Observable.just(count);
}
return Observable.error(error);
}
}))
.test()
.assertFailure(RuntimeException.class);
关于rx-java2 - 我们如何在 retryWhen() 停止重试后获取 Throwable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49111878/