[英]In RxJava, how to reflect/extract a failure outside of an Observable?
我们有一个StoreService,它调用一个update(key,content)方法,该方法正在使用couchbase客户端进行get-> change_content-> replace。
作为该过程的一部分,我们使用Observable retryWhen来处理异常。 如果重试次数超过了最大重试次数,它只会传递Exception,然后触发观察者的onError方法。
万一无法处理错误,我们想做的就是将update(key,content)方法中的Exception抛出给调用它的StoreService,但我们没有这样做。
public void update(String key, ConversationDto updateConversationDto) {
ObservableExecution observableExecution = new ObservableExecution();
Observable
.defer(... get the document from couchbase ...)
.map(... handle JSON conversion and update the document ...)
.flatMap(documentUpdate -> {
return couchbaseClient.getAsyncBucket().replace(documentUpdate);
})
.retryWhen(new RetryWithDelay(3, 200))
.subscribe(
n -> logger.debug("on next update document -> " + n.content()),
e -> {
//logger.error("failed to insert a document",e);
observableExecution.setFailure(e);
},
() -> logger.debug("on complete update document")
);
// this is never true
if (observableExecution.isFailed()) {
final Throwable e = observableExecution.getFailure();
throw new DalRuntimeException(e.getMessage(), e);
}
}
这是retryWhen代码:
public Observable<?> call(Observable<? extends Throwable> attempts) {
return attempts
.flatMap(new Func1<Throwable, Observable<?>>() {
@Override
public Observable<?> call(Throwable errorNotification) {
if (++retryCount < maxRetries) {
// When this Observable calls onNext, the original
// Observable will be retried (i.e. re-subscribed).
logger.debug(errorNotification + " retry no. " + retryCount);
return Observable.timer(retryDelayMillis,
TimeUnit.MILLISECONDS);
}
// Max retries hit. Just pass the error along.
logger.debug(errorNotification + " exceeded max retries " + maxRetries);
return Observable.error(errorNotification);
}
});
}
非常感谢您的帮助!
订阅将异步运行,因此isFailed()
检查将始终在e -> setFailure(e)
代码运行之前立即运行。
正确的方法是从update()
方法返回Observable
并在StoreService
中对其进行StoreService
。 这样一来,您就可以在处理成功和失败时收到通知。
我同意@Ross:从概念上讲Observable应该由update()返回。 我可以提出的唯一简化方法是使用局部可变变量而不是ObservableExecution DTO:
public void update(String key, ConversationDto updateConversationDto) {
final Throwable[] errorHolder = new Throwable[1];
Observable
.defer(... get the document from couchbase ...)
.map(... handle JSON conversion and update the document ...)
.flatMap(documentUpdate -> {
return couchbaseClient.getAsyncBucket().replace(documentUpdate);
})
.retryWhen(new RetryWithDelay(3, 200))
.subscribe(
n -> logger.debug("on next update document -> " + n.content()),
e -> {
//logger.error("failed to insert a document",e);
errorHolder[0] = e;
},
() -> logger.debug("on complete update document")
);
if (errorHolder[0] != null) {
final Throwable e = errorHolder[0];
throw new DalRuntimeException(e.getMessage(), e);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.