You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
One of the design goals of 2.x was that no errors can be lost. Sometimes, the sequence ends or gets cancelled before the source could emit an onError which has nowhere to go at that point and gets routed to the RxJavaPlugins.onError.
Unlike 1.x, 2.x by default calls Thread.currentThread().getUncaughtExceptionHandler().uncaughtException() which crashes an Android app. Many developers have noticed the increased number of app crashes when porting to 2.x due to this behavior change. Note that this doesn't mean RxJava 2 is unstable but it means you likely had these exceptions all along but they were silently dropped.
Unfortunately, RxJava can't tell which of these out-of-lifecycle, undeliverable exceptions should or shouldn't crash your app. Identifying the source and reason for these exceptions can be tiresome, especially if they originate from a source and get routed to RxJavaPlugins.onError somewhere lower the chain.
Therefore, 2.0.6 introduces specific exception wrappers to help distinguish and track down what was happening the time of the error:
OnErrorNotImplementedException: reintroduced to detect when the user forgot to add error handling to subscribe().
ProtocolViolationException: indicates a bug in an operator
UndeliverableException: wraps the original exception that can't be delivered due to lifecycle restrictions on a Subscriber/Observer. It is automatically applied by RxJavaPlugins.onError with intact stacktrace that may help find which exact operator rerouted the original error.
If an undeliverable exception is an instance/descendant of NullPointerException, IllegalStateException (UndeliverableException and ProtocolViolationException extend this), IllegalArgumentException, CompositeException, MissingBackpressureException or OnErrorNotImplementedException, the UndeliverableException wrapping doesn't happen.
In addition, some 3rd party libraries/code throw when they get interrupted by a cancel/dispose call which leads to an undeliverable exception most of the time. Internal changes in 2.0.6 now consistently cancel or dispose a Subscription/Disposable before cancelling/disposing a task or worker (which causes the interrupt on the target thread).
// in some librarytry {
doSomethingBlockingly()
} catch (InterruptedExceptionex) {
// check if the interrupt is due to cancellation// if so, no need to signal the InterruptedExceptionif (!disposable.isDisposed()) {
observer.onError(ex);
}
}
If the library/code already did this, the undeliverable InterruptedExceptions should stop now. If this pattern was not employed before, we encourage updating the code/library in question.
API enhancements
Pull 5036: Reintroduce OnErrorNotImplementedException for 0-1 arg subscribe.
Version 2.0.6 - February 15, 2017 (Maven)
Undeliverable exceptions
One of the design goals of 2.x was that no errors can be lost. Sometimes, the sequence ends or gets cancelled before the source could emit an
onError
which has nowhere to go at that point and gets routed to theRxJavaPlugins.onError
.Unlike 1.x, 2.x by default calls
Thread.currentThread().getUncaughtExceptionHandler().uncaughtException()
which crashes an Android app. Many developers have noticed the increased number of app crashes when porting to 2.x due to this behavior change. Note that this doesn't mean RxJava 2 is unstable but it means you likely had these exceptions all along but they were silently dropped.Unfortunately, RxJava can't tell which of these out-of-lifecycle, undeliverable exceptions should or shouldn't crash your app. Identifying the source and reason for these exceptions can be tiresome, especially if they originate from a source and get routed to
RxJavaPlugins.onError
somewhere lower the chain.Therefore, 2.0.6 introduces specific exception wrappers to help distinguish and track down what was happening the time of the error:
OnErrorNotImplementedException
: reintroduced to detect when the user forgot to add error handling tosubscribe()
.ProtocolViolationException
: indicates a bug in an operatorUndeliverableException
: wraps the original exception that can't be delivered due to lifecycle restrictions on aSubscriber
/Observer
. It is automatically applied byRxJavaPlugins.onError
with intact stacktrace that may help find which exact operator rerouted the original error.If an undeliverable exception is an instance/descendant of
NullPointerException
,IllegalStateException
(UndeliverableException
andProtocolViolationException
extend this),IllegalArgumentException
,CompositeException
,MissingBackpressureException
orOnErrorNotImplementedException
, theUndeliverableException
wrapping doesn't happen.In addition, some 3rd party libraries/code throw when they get interrupted by a cancel/dispose call which leads to an undeliverable exception most of the time. Internal changes in 2.0.6 now consistently cancel or dispose a
Subscription
/Disposable
before cancelling/disposing a task or worker (which causes the interrupt on the target thread).If the library/code already did this, the undeliverable
InterruptedException
s should stop now. If this pattern was not employed before, we encourage updating the code/library in question.API enhancements
OnErrorNotImplementedException
for 0-1 arg subscribe.RxJavaPlugins
, add missing params validationSingle.doAfterTerminate
Bugfixes
replay()
cancel/disposeNullPointerException
.scan(seed, f)
to emit accumulated values without delay.Other
Single.zip
implementation, no dispose on all-success.amb
subscription ordering.@Nonnull
annotations.@Nullable
annotation toSimpleQueue
.errorHandler
.RxJavaPlugins
.Completable.subscribe
.The text was updated successfully, but these errors were encountered: