Observable.empty() causes java.util.NoSuchElementException: Sequence contains no elements

Anton Shkurenko picture Anton Shkurenko · Oct 8, 2015 · Viewed 12.1k times · Source

I'm using Retrofit 2.0.0-beta2 with RxJava 1.0.14. I handle errors this way because I need to execute some code in doFinally:

.onErrorResumeNext(Observable.empty());

But when I get a http response with an error (401 for example) my app crashes with no my classes in the stack trace. Nothing bad happens if use Observable.never. Here's full stack trace:

java.lang.IllegalStateException: Exception thrown on Scheduler.Worker thread. Add `onError` handling.
at rx.internal.schedulers.ScheduledAction.run (ScheduledAction.java:60)
at android.os.Handler.handleCallback (Handler.java:739)
at android.os.Handler.dispatchMessage (Handler.java:95)
at android.os.Looper.loop (Looper.java:135)
at android.app.ActivityThread.main (ActivityThread.java:5221)
at java.lang.reflect.Method.invoke (Unknown source)
at java.lang.reflect.Method.invoke (Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:694)

rx.exceptions.OnErrorNotImplementedException: Sequence contains no elements
at rx.Observable$27.onError (Observable.java:7535)
at rx.observers.SafeSubscriber._onError (SafeSubscriber.java:154)
at rx.observers.SafeSubscriber.onError (SafeSubscriber.java:111)
at rx.internal.operators.OperatorDoOnEach$1.onError (OperatorDoOnEach.java:70)
at rx.internal.operators.OperatorDoOnEach$1.onError (OperatorDoOnEach.java:70)
at rx.internal.operators.OperatorDoOnEach$1.onError (OperatorDoOnEach.java:70)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue (OperatorObserveOn.java:197)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call (OperatorObserveOn.java:170)
at rx.internal.schedulers.ScheduledAction.run (ScheduledAction.java:55)
at android.os.Handler.handleCallback (Handler.java:739)
at android.os.Handler.dispatchMessage (Handler.java:95)
at android.os.Looper.loop (Looper.java:135)
at android.app.ActivityThread.main (ActivityThread.java:5221)
at java.lang.reflect.Method.invoke (Unknown source)
at java.lang.reflect.Method.invoke (Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:694)

java.util.NoSuchElementException: Sequence contains no elements
at rx.internal.operators.OperatorSingle$ParentSubscriber.onCompleted (OperatorSingle.java:131)
at rx.internal.operators.OperatorTake$1.onCompleted (OperatorTake.java:53)
at rx.Observable$EmptyHolder$1.call (Observable.java:1077)
at rx.Observable$EmptyHolder$1.call (Observable.java:1074)
at rx.Observable.unsafeSubscribe (Observable.java:7710)
at rx.internal.operators.OperatorOnErrorResumeNextViaObservable$1.onError (OperatorOnErrorResumeNextViaObservable.java:76)
at rx.internal.operators.OperatorDoOnEach$1.onError (OperatorDoOnEach.java:70)
at rx.internal.operators.OperatorSubscribeOn$1$1$1.onError (OperatorSubscribeOn.java:71)
at rx.observers.SerializedObserver.onError (SerializedObserver.java:159)
at rx.observers.SerializedSubscriber.onError (SerializedSubscriber.java:79)
at rx.internal.operators.OperatorTakeUntil$1.onError (OperatorTakeUntil.java:49)
at rx.internal.operators.OperatorMerge$MergeSubscriber.reportError (OperatorMerge.java:239)
at rx.internal.operators.OperatorMerge$MergeSubscriber.checkTerminate (OperatorMerge.java:774)
at rx.internal.operators.OperatorMerge$MergeSubscriber.emitLoop (OperatorMerge.java:532)
at rx.internal.operators.OperatorMerge$MergeSubscriber.emit (OperatorMerge.java:521)
at rx.internal.operators.OperatorMerge$InnerSubscriber.onError (OperatorMerge.java:808)
at rx.Observable$ThrowObservable$1.call (Observable.java:9600)
at rx.Observable$ThrowObservable$1.call (Observable.java:9590)
at rx.Observable.unsafeSubscribe (Observable.java:7710)
at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext (OperatorMerge.java:231)
at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext (OperatorMerge.java:140)
at rx.internal.operators.OperatorMap$1.onNext (OperatorMap.java:55)
at retrofit.RxJavaCallAdapterFactory$CallOnSubscribe.call (RxJavaCallAdapterFactory.java:113)
at retrofit.RxJavaCallAdapterFactory$CallOnSubscribe.call (RxJavaCallAdapterFactory.java:88)
at rx.Observable$2.call (Observable.java:162)
at rx.Observable$2.call (Observable.java:154)
at rx.Observable$2.call (Observable.java:162)
at rx.Observable$2.call (Observable.java:154)
at rx.Observable$2.call (Observable.java:162)
at rx.Observable$2.call (Observable.java:154)
at rx.Observable.unsafeSubscribe (Observable.java:7710)
at rx.internal.operators.OperatorSubscribeOn$1$1.call (OperatorSubscribeOn.java:62)
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)

Thanks,
Anton

Answer

Jake Wharton picture Jake Wharton · Oct 8, 2015

From the stack trace,

at rx.internal.operators.OperatorSingle$ParentSubscriber.onCompleted (OperatorSingle.java:131)
at rx.internal.operators.OperatorTake$1.onCompleted (OperatorTake.java:53)

This equates to take(1).single() which is also the first() convenience operator. I suspect you are using the latter, but both require at least one element.

By using empty(), you are creating an observable with no elements which violates the contract of the downstream operators. Either emit a default item in the onErrorResumeNext observable or change your downstream code to support streams with no elements.