src/main/java/io/reactivex/Observable.java
@CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    public final Observable<T> retryWhen(
            final Function<? super Observable<Throwable>, ? extends ObservableSource<?>> handler) {
        ObjectHelper.requireNonNull(handler, "handler is null");
        return RxJavaPlugins.onAssembly(new ObservableRetryWhen<T>(this, handler));
    }
@CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    public final Observable<T> retryWhen(
            final Function<? super Observable<Throwable>, ? extends ObservableSource<?>> handler) {
        ObjectHelper.requireNonNull(handler, "handler is null");
        return RxJavaPlugins.onAssembly(new ObservableRetryWhen<T>(this, handler));
    }
Returns an Observable that emits the same values as the source ObservableSource with the exception of an
{@code onError}. An {@code onError} notification from the source will result in the emission of a
{@link Throwable} item to the ObservableSource provided as an argument to the {@code notificationHandler}
function. If that ObservableSource calls {@code onComplete} or {@code onError} then {@code retry} will call
{@code onComplete} or {@code onError} on the child subscription. Otherwise, this ObservableSource will
resubscribe to the source ObservableSource.
<p>
<img width="640" height="430" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/retryWhen.f.png" alt="">
<p>
Example:

This retries 3 times, each time incrementing the number of seconds it waits.

<pre><code>
Observable.create((ObservableEmitter&lt;? super String&gt; s) -&gt; {
System.out.println("subscribing");
s.onError(new RuntimeException("always fails"));
}).retryWhen(attempts -&gt; {
return attempts.zipWith(Observable.range(1, 3), (n, i) -&gt; i).flatMap(i -&gt; {
System.out.println("delay retry by " + i + " second(s)");
return Observable.timer(i, TimeUnit.SECONDS);
});
}).blockingForEach(System.out::println);
</code></pre>

Output is:

<pre> {@code
subscribing
delay retry by 1 second(s)
subscribing
delay retry by 2 second(s)
subscribing
delay retry by 3 second(s)
subscribing
} </pre>
<p>
Note that the inner {@code ObservableSource} returned by the handler function should signal
either {@code onNext}, {@code onError} or {@code onComplete} in response to the received
{@code Throwable} to indicate the operator should retry or terminate. If the upstream to
the operator is asynchronous, signalling onNext followed by onComplete immediately may
result in the sequence to be completed immediately. Similarly, if this inner
{@code ObservableSource} signals {@code onError} or {@code onComplete} while the upstream is
active, the sequence is terminated with the same signal immediately.
<p>
The following example demonstrates how to retry an asynchronous source with a delay:
<pre><code>
Observable.timer(1, TimeUnit.SECONDS)
.doOnSubscribe(s -&gt; System.out.println("subscribing"))
.map(v -&gt; { throw new RuntimeException(); })
.retryWhen(errors -&gt; {
AtomicInteger counter = new AtomicInteger();
return errors
.takeWhile(e -&gt; counter.getAndIncrement() != 3)
.flatMap(e -&gt; {
System.out.println("delay retry by " + counter.get() + " second(s)");
return Observable.timer(counter.get(), TimeUnit.SECONDS);
});
})
.blockingSubscribe(System.out::println, System.out::println);
</code></pre>
<dl>
<dt><b>Scheduler:</b></dt>
<dd>{@code retryWhen} does not operate by default on a particular {@link Scheduler}.</dd>
</dl>

@param handler
receives an ObservableSource of notifications with which a user can complete or error, aborting the
retry
@return the source ObservableSource modified with retry logic
@see <a href="http://reactivex.io/documentation/operators/retry.html">ReactiveX operators documentation: Retry</a>