question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Actual exception is being hidden by OnErrorFailedException

See original GitHub issue

Using RxJava 1.10 (and similar issue on 1.0.15), I stumbled upon a mysterious stack trace that made no sense in my app, after a lot of debugging, I found that RxJava will report the wrong exception in some scenarios. For example, if you run this sample code:

Observable.just(1).doOnNext(new Action1<Integer>() {
        @Override public void call(Integer val) {
            throw new IllegalStateException("doOnNextException");
        }
    }).retryWhen(new Func1<Observable<? extends Throwable>, Observable<?>>() {
        @Override public Observable<?> call(Observable<? extends Throwable> errorObservable) {
            return errorObservable.flatMap(new Func1<Throwable, Observable<?>>() {
                @Override public Observable<?> call(Throwable throwable) {
                    return Observable.just(3).delay(1, TimeUnit.SECONDS).doOnNext(
                            new Action1<Integer>() {
                                @Override public void call(Integer integer) {
                                    throw new UnsupportedOperationException("retry exception");
                                }
                            });
                }
            });
        }
    }).subscribe(new Subscriber<Integer>() {
        @Override public void onCompleted() {
            Log.v("EX", "onCompleted");
        }

        @Override public void onError(Throwable e) {
            Log.v("EX", "onError");
            throw new IllegalThreadStateException();
        }

        @Override public void onNext(Integer integer) {
            Log.v("EX", "onNext");
        }
    });

The expected behaviour should be that IllegalThreadStateException (thrown within the onError handler of the subscriber) is included as the cause. However, the actual stack trace contains UnsupportedOperationException as the cause - which is not the problem in the code snippet above. the UnsupportedOperationException is totally fine, but the problem arises when onError throws.

This leads to a stack trace that points to the wrong cause and does not include the actual cause (which would be the IllegalThreadStateException). If I removed the retryWhen() block - then the stack trace correctly includes IllegalThreadStateException as the exception from within onError.

The (incorrect) trace from the code snippet above:

Process: com.example.mydemoapp, PID: 14118
java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)
 Caused by: rx.exceptions.OnErrorFailedException: Error occurred when trying to propagate error to Observer.onError
    at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:194)
    at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120)
    at rx.internal.operators.OnSubscribeRedo$4$1.onError(OnSubscribeRedo.java:331)
    at rx.internal.operators.OperatorMerge$MergeSubscriber.reportError(OperatorMerge.java:240)
    at rx.internal.operators.OperatorMerge$MergeSubscriber.checkTerminate(OperatorMerge.java:776)
    at rx.internal.operators.OperatorMerge$MergeSubscriber.emitLoop(OperatorMerge.java:537)
    at rx.internal.operators.OperatorMerge$MergeSubscriber.emit(OperatorMerge.java:526)
    at rx.internal.operators.OperatorMerge$InnerSubscriber.onError(OperatorMerge.java:810)
    at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:71)
    at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:187)
    at rx.internal.operators.OperatorDoOnEach$1.onNext(OperatorDoOnEach.java:82)
    at rx.internal.operators.OperatorDelay$1$3.call(OperatorDelay.java:88)
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
    at java.lang.Thread.run(Thread.java:818) 
 Caused by: rx.exceptions.CompositeException: 2 exceptions occurred. 
    at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:194) 
    at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120) 
    at rx.internal.operators.OnSubscribeRedo$4$1.onError(OnSubscribeRedo.java:331) 
    at rx.internal.operators.OperatorMerge$MergeSubscriber.reportError(OperatorMerge.java:240) 
    at rx.internal.operators.OperatorMerge$MergeSubscriber.checkTerminate(OperatorMerge.java:776) 
    at rx.internal.operators.OperatorMerge$MergeSubscriber.emitLoop(OperatorMerge.java:537) 
    at rx.internal.operators.OperatorMerge$MergeSubscriber.emit(OperatorMerge.java:526) 
    at rx.internal.operators.OperatorMerge$InnerSubscriber.onError(OperatorMerge.java:810) 
    at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:71) 
    at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:187) 
    at rx.internal.operators.OperatorDoOnEach$1.onNext(OperatorDoOnEach.java:82) 
    at rx.internal.operators.OperatorDelay$1$3.call(OperatorDelay.java:88) 
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
    at java.lang.Thread.run(Thread.java:818) 
 Caused by: rx.exceptions.CompositeException$CompositeExceptionCausalChain: Chain of Causes for CompositeException In Order Received =>
    at android.util.Log.getStackTraceString(Log.java:504)
    at com.android.internal.os.RuntimeInit.Clog_e(RuntimeInit.java:59)
    at com.android.internal.os.RuntimeInit.access$200(RuntimeInit.java:43)
    at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:91)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:66)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
    at java.lang.Thread.run(Thread.java:818) 
 Caused by: java.lang.UnsupportedOperationException: retry exception
    at com.example.mydemoapp.MainActivity$3$1$1.call(MainActivity.java:74)
    at com.example.mydemoapp.MainActivity$3$1$1.call(MainActivity.java:72)
    at rx.Observable$11.onNext(Observable.java:4445)
    at rx.internal.operators.OperatorDoOnEach$1.onNext(OperatorDoOnEach.java:80)
    at rx.internal.operators.OperatorDelay$1$3.call(OperatorDelay.java:88)
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
    at java.lang.Thread.run(Thread.java:818) 
 Caused by: rx.exceptions.OnErrorThrowable$OnNextValue: OnError while emitting onNext value: 3
    at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:187)
    at rx.internal.operators.OperatorDoOnEach$1.onNext(OperatorDoOnEach.java:82)
    at rx.internal.operators.OperatorDelay$1$3.call(OperatorDelay.java:88) 
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
    at java.lang.Thread.run(Thread.java:818) 

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
akarnokdcommented, Feb 9, 2016

You shoudn’t throw from Observer.onError or Subscriber.onError but there are safeguards which have to wrap exceptions and deliver it somewhere upstream.

0reactions
zsxwingcommented, Jun 2, 2016

Closing via #3977

Read more comments on GitHub >

github_iconTop Results From Across the Web

Android JAVA RX exception only from the play store
Your code is throwing an exception that is not caught. Have you specified an function for onError? [Your Observable].subscribe(value ...
Read more >
OnErrorFailedException (RxJava Javadoc 1.3.8) - ReactiveX
public class OnErrorFailedException extends java.lang.RuntimeException. Represents an exception used to re-throw errors thrown from Observer.
Read more >
CHANGES.md · v1.0.0-rc.5 · 硅谷海盗 / RxJava · GitCode
onNext(t); } catch (MissingBackpressureException e) { // fail if the upstream ... This is being done so that the 1.x version can be...
Read more >
rx.Observable Maven / Gradle / Ivy - Download JAR files
If the source Observable emits more than one item or no items, notify of an * {@code IllegalArgumentException} or {@code NoSuchElementException} ...
Read more >
Open Source Used In AppDynamics_Cloud_Monitoring 2785
jar/rx/exceptions/OnErrorFailedException.java. * /opt/ws_local/PERMITS_SQL/1014221113_1591382734.95/0/rxjava-1-3-8-sources-jar/rx/functions/Func1.java.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found