Catch recover from an onError notification by continuing the sequence without error The Catch operator intercepts an onError
notification from the source Observable and, instead of passing it through to any observers, replaces it with some other item or sequence of items, potentially allowing the resulting Observable to terminate normally or not to terminate at all.
There are several variants of the Catch operator, and a variety of names used by different ReactiveX implementations to describe this operation, as you can see in the sections below.
In some ReactiveX implementations, there is an operator called something like “OnErrorResumeNext” that behaves like a Catch variant: specifically reacting to an onError
notification from the source Observable. In others, there is an operator with that name that behaves more like a Concat variant: performing the concatenation operation regardless of whether the source Observable terminates normally or with an error. This is unfortunate and confusing, but something we have to live with.
See Also Language-Specific Information
RxClojure catch*
RxClojure implements this operator as catch*
. This operator takes two arguments, both of which are functions of your choosing that take the exception raised by onError
as their single parameters. The first function is a predicate. If it returns false
, catch*
passes the onError
notification unchanged to its observers. If it returns true
, however, catch*
swallows the error, calls the second function (which returns an Observable), and passes along the emissions and notifications from this new Observable to its observers.
You may replace the first function parameter (the predicate that evaluates the exception) with a class object representing a variety of exception. If you do this, catch*
will treat it as equivalent to predicate that performs an instance?
check to see if the exception from the onError
notification is an instance of the class object. In other words:
Sample Code (->> my-observable
(catch* IllegalArgumentException
(fn [e] (rx/return 1)))
) is equivalent to:
(->> my-observable
(catch* (fn [e] (-> instance? IllegalArgumentException e))
(fn [e] (rx/return 1)))
)
RxCpp RxCpp does not implement the Catch operator.
RxGroovy onErrorResumeNext onErrorReturn onExceptionResumeNext
RxGroovy implements the Catch operator in the same way as does RxJava. There are three distinct operators that provide this functionality:
onErrorReturn
instructs an Observable to emit a particular item when it encounters an error, and then terminate normally onErrorResumeNext
instructs an Observable to begin emitting a second Observable sequence if it encounters an error onExceptionResumeNext
instructs an Observable to continue emitting items after it encounters an exception (but not another variety of throwable) onErrorReturn
The onErrorReturn
method returns an Observable that mirrors the behavior of the source Observable, unless that Observable invokes onError
in which case, rather than propagating that error to the observer, onErrorReturn
will instead emit a specified item and invoke the observer’s onCompleted
method, as shown in the following sample code:
Sample Code def myObservable = Observable.create({ aSubscriber ->
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('Four');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('Three');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('Two');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('One');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onError();
});
myObservable.onErrorReturn({ return('Blastoff!'); }).subscribe(
{ println(it); }, // onNext
{ println("Error: " + it.getMessage()); }, // onError
{ println("Sequence complete"); } // onCompleted
); Four
Three
Two
One
Blastoff!
Sequence complete onErrorResumeNext
The onErrorResumeNext
method returns an Observable that mirrors the behavior of the source Observable, unless that Observable invokes onError
in which case, rather than propagating that error to the observer, onErrorResumeNext
will instead begin mirroring a second, backup Observable, as shown in the following sample code:
Sample Code def myObservable = Observable.create({ aSubscriber ->
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('Three');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('Two');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('One');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onError();
});
def myFallback = Observable.create({ aSubscriber ->
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('0');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('1');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('2');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onCompleted();
});
myObservable.onErrorResumeNext(myFallback).subscribe(
{ println(it); }, // onNext
{ println("Error: " + it.getMessage()); }, // onError
{ println("Sequence complete"); } // onCompleted
); Three
Two
One
0
1
2
Sequence complete onExceptionResumeNext
Much like onErrorResumeNext
method, this returns an Observable that mirrors the behavior of the source Observable, unless that Observable invokes onError
in which case, if the Throwable passed to onError
is an Exception, rather than propagating that Exception to the observer, onExceptionResumeNext
will instead begin mirroring a second, backup Observable. If the Throwable is not an Exception, the Observable returned by onExceptionResumeNext
will propagate it to its observer’s onError
method and will not invoke its backup Observable.
RxJava 1․x onErrorResumeNext onErrorReturn onExceptionResumeNext
RxJava implements the Catch operator with three distinct operators:
onErrorReturn
instructs an Observable to emit a particular item when it encounters an error, and then terminate normally onErrorResumeNext
instructs an Observable to begin emitting a second Observable sequence if it encounters an error onExceptionResumeNext
instructs an Observable to continue emitting items after it encounters an exception (but not another variety of throwable) onErrorReturn
The onErrorReturn
method returns an Observable that mirrors the behavior of the source Observable, unless that Observable invokes onError
in which case, rather than propagating that error to the observer, onErrorReturn
will instead emit a specified item and invoke the observer’s onCompleted
method.
onErrorResumeNext
The onErrorResumeNext
method returns an Observable that mirrors the behavior of the source Observable, unless that Observable invokes onError
in which case, rather than propagating that error to the observer, onErrorResumeNext
will instead begin mirroring a second, backup Observable.
onExceptionResumeNext
Much like onErrorResumeNext
method, this returns an Observable that mirrors the behavior of the source Observable, unless that Observable invokes onError
in which case, if the Throwable passed to onError
is an Exception, rather than propagating that Exception to the observer, onExceptionResumeNext
will instead begin mirroring a second, backup Observable. If the Throwable is not an Exception, the Observable returned by onExceptionResumeNext
will propagate it to its observer’s onError
method and will not invoke its backup Observable.
RxJS catch onErrorResumeNext
RxJS implements the Catch operator with two distinct operators:
catch
instructs an Observable to begin emitting a second Observable sequence if it encounters an error onErrorResumeNext
instructs an Observable to begin emitting a second Observable sequence if it encounters an error or if the source Observable terminates normally catch
catch
is found in the following distributions:
rx.js
rx.all.js
rx.all.compat.js
rx.compat.js
rx.lite.js
rx.lite.compat.js
onErrorResumeNext
This implementation borrows the confusing nomenclature from Rx.NET, in which onErrorResumeNext
switches to a back-up Observable both on an error and on a normal, error-free termination of the source Observable.
onErrorResumeNext
is found in the following distributions:
RxKotlin onErrorResumeNext onErrorReturn onExceptionResumeNext
RxKotlin implements the Catch operator in the same way as does RxJava. There are three distinct operators that provide this functionality:
onErrorReturn
instructs an Observable to emit a particular item when it encounters an error, and then terminate normally onErrorResumeNext
instructs an Observable to begin emitting a second Observable sequence if it encounters an error onExceptionResumeNext
instructs an Observable to continue emitting items after it encounters an exception (but not another variety of throwable) onErrorReturn
The onErrorReturn
method returns an Observable that mirrors the behavior of the source Observable, unless that Observable invokes onError
in which case, rather than propagating that error to the observer, onErrorReturn
will instead emit a specified item and invoke the observer’s onCompleted
method.
onErrorResumeNext
The onErrorResumeNext
method returns an Observable that mirrors the behavior of the source Observable, unless that Observable invokes onError
in which case, rather than propagating that error to the observer, onErrorResumeNext
will instead begin mirroring a second, backup Observable.
onExceptionResumeNext
Much like onErrorResumeNext
method, this returns an Observable that mirrors the behavior of the source Observable, unless that Observable invokes onError
in which case, if the Throwable passed to onError
is an Exception, rather than propagating that Exception to the observer, onExceptionResumeNext
will instead begin mirroring a second, backup Observable. If the Throwable is not an Exception, the Observable returned by onExceptionResumeNext
will propagate it to its observer’s onError
method and will not invoke its backup Observable.
RxNET Catch OnErrorResumeNext
Rx.NET implements the Catch operator with two distinct operators:
Catch
instructs an Observable to begin emitting a second Observable sequence if it encounters an error OnErrorResumeNext
instructs an Observable to begin emitting a second Observable sequence if it encounters an error or if the source Observable terminates normally Catch
The Catch
operator has a variant that allows you to specify which sort of Exception you want to catch. If you use that variant of the operator, any other Exceptions will be passed through to the observer as if the Catch
operator had not been applied.
OnErrorResumeNext
This implementation introduces a confusing nomenclature, in which in spite of its name OnErrorResumeNext
switches to a back-up Observable both on an error and on a normal, error-free termination of the source Observable. It is therefore more like a concatenation operator.
RxPHP catch
RxPHP implements this operator as catch
.
Continues an observable sequence that is terminated by an exception with the next observable sequence.
Sample Code //from https://github.com/ReactiveX/RxPHP/blob/master/demo/catch/catch.php
$obs2 = Rx\Observable::of(42);
$source = \Rx\Observable::error(new Exception('Some error'))
->catch(function (Throwable $e, \Rx\Observable $sourceObs) use ($obs2) {
return $obs2;
});
$subscription = $source->subscribe($stdoutObserver);
RxPY catch_exception on_error_resume_next
RxPY implements the Catch operator with two distinct operators:
catch_exception
instructs an Observable, if it encounters an error, to begin emitting items from a set of other Observables, one Observable at a time, until one of those Observables terminates successfully on_error_resume_next
instructs an Observable to concatenate items emitted by a set of other Observables, one Observable at a time, regardless of whether the source Observable or any subsequent Observable terminates with an error catch_exception
You may pass catch_exception
a set of back-up Observables either as individual function parameters or as a single array of Observables. If it encounters an onError
notification from the source Observable, it will subscribe to and begin mirroring the first of these back-up Observables. If this back-up Observable itself issues an onError
notification, catch_exception
will swallow it and switch over to the next back-up Observable. If any of these Observables issues an onCompleted
notification, catch_exception
will pass this along and will stop.
on_error_resume_next
You may pass on_error_resume_next
a set of back-up Observables either as individual function parameters, as a single array of Observables, or as a factory function that generates Observables. When the source Observable terminates, whether normally or with an error, on_error_resume_next
will subscribe to and begin mirroring the first of these back-up Observables, and then will recursively continue this concatenation process for each additional Observable until there are no more Observables to mirror, at which time it will pass on the onError
or onCompleted
notification from the last of these Observables.
Rxrb on_error_resume_next rescue_error
Rx.rb implements the Catch operator with two distinct operators:
rescue_error
instructs an Observable to begin emitting items from another Observable, or from an Observable returned from an action, if it encounters an error on_error_resume_next
instructs an Observable to concatenate items emitted by another Observable to the sequence emitted by the source Observable, regardless of whether the source Observable terminates normally or with an error rescue_error
You may pass rescue_error
either an Observable or a factory action that generates an Observable.
on_error_resume_next
In Rx.rb, on_error_resume_next
inherits the misleading nomenclature from Rx.NET in that it concatenates the second Observable sequence to the source sequence whether that source sequence terminates normally or with an error.
RxScala onErrorFlatMap onErrorResumeNext onErrorReturn onExceptionResumeNext
Rx.rb implements the Catch operator with four distinct operators:
onErrorFlatMap
replaces all onError
notifications from a misbehaving Observable into the emissions from a secondary Observable onErrorResumeNext
instructs an Observable to begin emitting a second Observable sequence if it encounters an error onErrorReturn
instructs an Observable to emit a particular item when it encounters an error, and then terminate normally onExceptionResumeNext
instructs an Observable to continue emitting items after it encounters an exception (but not another variety of throwable) onErrorFlatMap
onErrorFlatMap
handles a special case: a source Observable that is noncompliant with the Observable contract in such a way that it may interleave onError
notifications with its emissions without terminating. This operator allows you to replace those onError
notifications with the emissions of an Observable of your choosing without unsubscribing from the source, so that any future items emitted from the source will be passed along to observers as though the sequence had not been interrupted with an onError
notification.
Because onErrorFlatMap
is designed to work with pathological source Observables that do not terminate after issuing an error, it is mostly useful in debugging/testing scenarios.
Note that you should apply onErrorFlatMap
directly to the pathological source Observable, and not to that Observable after it has been modified by additional operators, as such operators may effectively renormalize the source Observable by unsubscribing from it immediately after it issues an error. Above, for example, is an illustration showing how onErrorFlatMap
will respond to two error-generating Observables that have been merged by the Merge operator:
Note that onErrorFlatMap
will not react to both errors generated by both Observables, but only to the single error passed along by merge
.
onErrorResumeNext
The onErrorResumeNext
method returns an Observable that mirrors the behavior of the source Observable, unless that Observable invokes onError
in which case, rather than propagating that error to the observer, onErrorResumeNext
will instead begin mirroring a second, backup Observable.
onErrorReturn
The onErrorReturn
method returns an Observable that mirrors the behavior of the source Observable, unless that Observable invokes onError
in which case, rather than propagating that error to the observer, onErrorReturn
will instead emit a specified item and invoke the observer’s onCompleted
method.
onExceptionResumeNext
Much like onErrorResumeNext
method, this returns an Observable that mirrors the behavior of the source Observable, unless that Observable invokes onError
in which case, if the Throwable passed to onError
is an Exception, rather than propagating that Exception to the observer, onExceptionResumeNext
will instead begin mirroring a second, backup Observable. If the Throwable is not an Exception, the Observable returned by onExceptionResumeNext
will propagate it to its observer’s onError
method and will not invoke its backup Observable.