Reputation: 4391
I have this code to attemp to connect to a xmpp server. Everything works fine except in the last attemp to try to connect, onError is not called on the subscriber and according to the doc, it should. What am i doing wrong?
@Override
public void connect(final AbstractXMPPConnection connection) {
Observable.<AbstractXMPPConnection>create(subscriber -> {
try {
connection.connect();
} catch (SmackException | IOException | XMPPException e) {
e.printStackTrace();
subscriber.onError(e);
}
})
.retryWhen(attempts -> attempts.zipWith(Observable.range(1, 4), (n, i) -> i).flatMap(i -> {
return Observable.timer(i, TimeUnit.SECONDS);
}))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<AbstractXMPPConnection>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
if (callback != null)
callback.onFailedConnecting();
}
@Override
public void onNext(AbstractXMPPConnection conn) {
if (callback != null)
callback.onConnected();
}
});
}
TLDR: on the last attempt, public void onError should be called and it is not
Upvotes: 1
Views: 1160
Reputation: 71
I made this such way (Scala, RxScala):
.retryWhen(_
.zipWith(Observable.just(1, 2, 3, -1))((t, i) => (t, i))
.flatMap( tuple => tuple match {
case (t, -1) => Observable.error(t)
case (t, i) => Observable.timer(i seconds)
}))
Maybe there is some kind of zipWith
operator, which calls onError
, with first non-pair element. It would be nice
Upvotes: 0
Reputation: 13450
You have:
.retryWhen(attempts -> attempts.zipWith(Observable.range(1, 4), (n, i) -> i).flatMap(i -> {
return Observable.timer(i, TimeUnit.SECONDS);
}))
this code will never emit an error so it will try exponentially (Timer) to retry but will never fail. Thus onError() will never be called.
If you want to catch the error either you need to pass it from the retryWhen with an explicit Observable.error() or delete the retryWhen part. :)
Upvotes: 1