Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when trying to connect too fast [UndeliverableException] #383

Closed
GuillaumeBourge opened this issue Mar 8, 2018 · 60 comments
Closed
Assignees
Labels
bug Bug that is caused by the library help wanted

Comments

@GuillaumeBourge
Copy link
Contributor

GuillaumeBourge commented Mar 8, 2018

lib version 1.5 rx2
I am facing issue in my app and in the sample app but i cannot find where the issue source is.

To reproduce, it's really easy, you have to try a connection just right after reactivate Bluetooth on the device (about 1 sec after). I think the GATT stack is not really ready but in fact it throw a disconnection although the connection process is not done. it's seems that a exception is not handle and rx is not happy but i am not sure.

logs :

03-08 14:47:18.292 11563-11677/com.polidea.rxandroidble.sample I/RxBle#ConnectionOperationQueue: Connection operations queue to be terminated (AA:BB:CC:11:22:33)
03-08 14:47:18.295 11563-11676/com.polidea.rxandroidble.sample D/RxBle#Executors$RunnableAdapter: Terminated.
03-08 14:47:18.297 11563-11677/com.polidea.rxandroidble.sample D/RxBle#ClientOperationQueue: QUEUED   ConnectOperation(154038096)
03-08 14:47:18.298 11563-11580/com.polidea.rxandroidble.sample D/RxBle#ClientOperationQueue: STARTED  ConnectOperation(154038096)
03-08 14:47:18.302 11563-11677/com.polidea.rxandroidble.sample D/RxBle#ClientOperationQueue: QUEUED   DisconnectOperation(110097737)
03-08 14:47:18.303 11563-11586/com.polidea.rxandroidble.sample W/System.err: io.reactivex.exceptions.UndeliverableException: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from AA:BB:CC:11:22:33
03-08 14:47:18.304 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:366)
03-08 14:47:18.304 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableUnsubscribeOn$UnsubscribeObserver.onError(ObservableUnsubscribeOn.java:67)
03-08 14:47:18.304 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onError(ObservableSubscribeOn.java:63)
03-08 14:47:18.304 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.tryOnError(ObservableCreate.java:85)
03-08 14:47:18.304 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onError(ObservableCreate.java:73)
03-08 14:47:18.304 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.internal.util.DisposableUtil$3.onError(DisposableUtil.java:60)
03-08 14:47:18.304 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.single.SingleDoFinally$DoFinallyObserver.onError(SingleDoFinally.java:81)
03-08 14:47:18.304 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.single.SingleTimeout$TimeoutMainObserver.onError(SingleTimeout.java:142)
03-08 14:47:18.304 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.single.SingleCreate$Emitter.tryOnError(SingleCreate.java:95)
03-08 14:47:18.304 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.single.SingleCreate$Emitter.onError(SingleCreate.java:81)
03-08 14:47:18.304 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.internal.util.DisposableUtil$1.onError(DisposableUtil.java:24)
03-08 14:47:18.305 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.flowable.FlowableElementAtSingle$ElementAtSubscriber.onError(FlowableElementAtSingle.java:101)
03-08 14:47:18.305 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.checkTerminate(FlowableFlatMap.java:566)
03-08 14:47:18.305 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.drainLoop(FlowableFlatMap.java:374)
03-08 14:47:18.305 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.drain(FlowableFlatMap.java:366)
03-08 14:47:18.305 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.innerError(FlowableFlatMap.java:605)
03-08 14:47:18.305 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFlatMap$InnerSubscriber.onError(FlowableFlatMap.java:668)
03-08 14:47:18.306 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.single.SingleToFlowable$SingleToFlowableObserver.onError(SingleToFlowable.java:68)
03-08 14:47:18.306 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableElementAtSingle$ElementAtObserver.onError(ObservableElementAtSingle.java:104)
03-08 14:47:18.306 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495)
03-08 14:47:18.306 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331)
03-08 14:47:18.306 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323)
03-08 14:47:18.306 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:571)
03-08 14:47:18.306 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.disposables.EmptyDisposable.error(EmptyDisposable.java:63)
03-08 14:47:18.306 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableError.subscribeActual(ObservableError.java:37)
03-08 14:47:18.306 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.307 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner(ObservableFlatMap.java:162)
03-08 14:47:18.307 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(ObservableFlatMap.java:139)
03-08 14:47:18.307 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.util.NotificationLite.accept(NotificationLite.java:246)
03-08 14:47:18.307 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableCache$ReplayDisposable.replay(ObservableCache.java:350)
03-08 14:47:18.307 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableCache.subscribeActual(ObservableCache.java:85)
03-08 14:47:18.307 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.307 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55)
03-08 14:47:18.307 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.307 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableElementAtSingle.subscribeActual(ObservableElementAtSingle.java:37)
03-08 14:47:18.307 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Single.subscribe(Single.java:3096)
03-08 14:47:18.307 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.single.SingleToFlowable.subscribeActual(SingleToFlowable.java:37)
03-08 14:47:18.308 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:13234)
03-08 14:47:18.308 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:13180)
03-08 14:47:18.308 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.onNext(FlowableFlatMap.java:163)
03-08 14:47:18.308 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFromArray$ArraySubscription.fastPath(FlowableFromArray.java:134)
03-08 14:47:18.308 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFromArray$BaseArraySubscription.request(FlowableFromArray.java:87)
03-08 14:47:18.308 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.onSubscribe(FlowableFlatMap.java:115)
03-08 14:47:18.308 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFromArray.subscribeActual(FlowableFromArray.java:37)
03-08 14:47:18.308 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:13234)
03-08 14:47:18.308 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:13180)
03-08 14:47:18.308 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFlatMapPublisher.subscribeActual(FlowableFlatMapPublisher.java:43)
03-08 14:47:18.308 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:13234)
03-08 14:47:18.309 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.flowable.FlowableElementAtSingle.subscribeActual(FlowableElementAtSingle.java:41)
03-08 14:47:18.309 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Single.subscribe(Single.java:3096)
03-08 14:47:18.309 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Single.subscribeWith(Single.java:3140)
03-08 14:47:18.309 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.internal.operations.ConnectOperation$4.subscribe(ConnectOperation.java:144)
03-08 14:47:18.309 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.single.SingleCreate.subscribeActual(SingleCreate.java:39)
03-08 14:47:18.309 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Single.subscribe(Single.java:3096)
03-08 14:47:18.310 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.single.SingleTimeout.subscribeActual(SingleTimeout.java:53)
03-08 14:47:18.310 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Single.subscribe(Single.java:3096)
03-08 14:47:18.310 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.single.SingleDoFinally.subscribeActual(SingleDoFinally.java:46)
03-08 14:47:18.310 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Single.subscribe(Single.java:3096)
03-08 14:47:18.311 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Single.subscribeWith(Single.java:3140)
03-08 14:47:18.313 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.internal.operations.ConnectOperation.protectedRun(ConnectOperation.java:79)
03-08 14:47:18.313 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.internal.QueueOperation$1.subscribe(QueueOperation.java:41)
03-08 14:47:18.313 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
03-08 14:47:18.313 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.314 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
03-08 14:47:18.314 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
03-08 14:47:18.314 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
03-08 14:47:18.314 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
03-08 14:47:18.314 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
03-08 14:47:18.314 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
03-08 14:47:18.314 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at java.lang.Thread.run(Thread.java:761)
03-08 14:47:18.315 11563-11586/com.polidea.rxandroidble.sample W/System.err: Caused by: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from AA:BB:CC:11:22:33
03-08 14:47:18.315 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter$1.apply(DisconnectionRouter.java:38)
03-08 14:47:18.315 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter$1.apply(DisconnectionRouter.java:35)
03-08 14:47:18.315 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:59)
03-08 14:47:18.315 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFilter$FilterObserver.onNext(ObservableFilter.java:52)
03-08 14:47:18.316 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableConcatMap$ConcatMapDelayErrorObserver.drain(ObservableConcatMap.java:464)
03-08 14:47:18.316 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableConcatMap$ConcatMapDelayErrorObserver.onSubscribe(ObservableConcatMap.java:324)
03-08 14:47:18.316 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFromArray.subscribeActual(ObservableFromArray.java:30)
03-08 14:47:18.316 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.316 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableConcatMap.subscribeActual(ObservableConcatMap.java:54)
03-08 14:47:18.316 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.316 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFilter.subscribeActual(ObservableFilter.java:30)
03-08 14:47:18.316 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.316 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:33)
03-08 14:47:18.316 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.316 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner(ObservableFlatMap.java:162)
03-08 14:47:18.316 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(ObservableFlatMap.java:139)
03-08 14:47:18.317 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFromArray$FromArrayDisposable.run(ObservableFromArray.java:107)
03-08 14:47:18.317 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFromArray.subscribeActual(ObservableFromArray.java:36)
03-08 14:47:18.317 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.317 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55)
03-08 14:47:18.317 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.317 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableElementAt.subscribeActual(ObservableElementAt.java:36)
03-08 14:47:18.317 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.317 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableCache$CacheState.connect(ObservableCache.java:216)
03-08 14:47:18.317 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableCache.subscribeActual(ObservableCache.java:82)
03-08 14:47:18.317 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.317 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11180)
03-08 14:47:18.317 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11058)
03-08 14:47:18.318 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter.<init>(DisconnectionRouter.java:60)
03-08 14:47:18.318 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter_Factory.get(DisconnectionRouter_Factory.java:33)
03-08 14:47:18.318 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter_Factory.get(DisconnectionRouter_Factory.java:10)
03-08 14:47:18.318 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at bleshadow.dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
03-08 14:47:18.318 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback_Factory.get(RxBleGattCallback_Factory.java:33)
03-08 14:47:18.318 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback_Factory.get(RxBleGattCallback_Factory.java:8)
03-08 14:47:18.318 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at bleshadow.dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
03-08 14:47:18.318 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.DaggerClientComponent$DeviceComponentImpl$ConnectionComponentImpl.connectOperation(DaggerClientComponent.java:713)
03-08 14:47:18.318 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.internal.connection.ConnectorImpl$1.call(ConnectorImpl.java:56)
03-08 14:47:18.318 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.internal.connection.ConnectorImpl$1.call(ConnectorImpl.java:41)
03-08 14:47:18.318 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableDefer.subscribeActual(ObservableDefer.java:32)
03-08 14:47:18.318 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.319 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableDoFinally.subscribeActual(ObservableDoFinally.java:45)
03-08 14:47:18.319 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.319 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableDefer.subscribeActual(ObservableDefer.java:39)
03-08 14:47:18.319 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.319 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableTakeUntil.subscribeActual(ObservableTakeUntil.java:41)
03-08 14:47:18.319 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.319 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableObserveOn.subscribeActual(ObservableObserveOn.java:45)
03-08 14:47:18.319 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.319 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.internal.operators.observable.ObservableDoFinally.subscribeActual(ObservableDoFinally.java:45)
03-08 14:47:18.319 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.319 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11180)
03-08 14:47:18.319 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:11109)
03-08 14:47:18.320 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.sample.example2_connection.ConnectionExampleActivity.onConnectToggleClick(ConnectionExampleActivity.java:52)
03-08 14:47:18.320 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.polidea.rxandroidble2.sample.example2_connection.ConnectionExampleActivity_ViewBinding$1.doClick(ConnectionExampleActivity_ViewBinding.java:43)
03-08 14:47:18.320 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at butterknife.internal.DebouncingOnClickListener.onClick(DebouncingOnClickListener.java:22)
03-08 14:47:18.320 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at android.view.View.performClick(View.java:5637)
03-08 14:47:18.320 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at android.view.View$PerformClick.run(View.java:22429)
03-08 14:47:18.320 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at android.os.Handler.handleCallback(Handler.java:751)
03-08 14:47:18.320 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
03-08 14:47:18.320 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at android.os.Looper.loop(Looper.java:154)
03-08 14:47:18.320 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6119)
03-08 14:47:18.320 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
03-08 14:47:18.320 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
03-08 14:47:18.320 11563-11586/com.polidea.rxandroidble.sample W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
03-08 14:47:18.322 11563-11586/com.polidea.rxandroidble.sample E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-1
                                                                                 Process: com.polidea.rxandroidble.sample, PID: 11563
                                                                                 io.reactivex.exceptions.UndeliverableException: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from AA:BB:CC:11:22:33
                                                                                     at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:366)
                                                                                     at io.reactivex.internal.operators.observable.ObservableUnsubscribeOn$UnsubscribeObserver.onError(ObservableUnsubscribeOn.java:67)
                                                                                     at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onError(ObservableSubscribeOn.java:63)
                                                                                     at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.tryOnError(ObservableCreate.java:85)
                                                                                     at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onError(ObservableCreate.java:73)
                                                                                     at com.polidea.rxandroidble2.internal.util.DisposableUtil$3.onError(DisposableUtil.java:60)
                                                                                     at io.reactivex.internal.operators.single.SingleDoFinally$DoFinallyObserver.onError(SingleDoFinally.java:81)
                                                                                     at io.reactivex.internal.operators.single.SingleTimeout$TimeoutMainObserver.onError(SingleTimeout.java:142)
                                                                                     at io.reactivex.internal.operators.single.SingleCreate$Emitter.tryOnError(SingleCreate.java:95)
                                                                                     at io.reactivex.internal.operators.single.SingleCreate$Emitter.onError(SingleCreate.java:81)
                                                                                     at com.polidea.rxandroidble2.internal.util.DisposableUtil$1.onError(DisposableUtil.java:24)
                                                                                     at io.reactivex.internal.operators.flowable.FlowableElementAtSingle$ElementAtSubscriber.onError(FlowableElementAtSingle.java:101)
                                                                                     at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.checkTerminate(FlowableFlatMap.java:566)
                                                                                     at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.drainLoop(FlowableFlatMap.java:374)
                                                                                     at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.drain(FlowableFlatMap.java:366)
                                                                                     at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.innerError(FlowableFlatMap.java:605)
                                                                                     at io.reactivex.internal.operators.flowable.FlowableFlatMap$InnerSubscriber.onError(FlowableFlatMap.java:668)
                                                                                     at io.reactivex.internal.operators.single.SingleToFlowable$SingleToFlowableObserver.onError(SingleToFlowable.java:68)
                                                                                     at io.reactivex.internal.operators.observable.ObservableElementAtSingle$ElementAtObserver.onError(ObservableElementAtSingle.java:104)
                                                                                     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495)
                                                                                     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331)
                                                                                     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323)
                                                                                     at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:571)
                                                                                     at io.reactivex.internal.disposables.EmptyDisposable.error(EmptyDisposable.java:63)
                                                                                     at io.reactivex.internal.operators.observable.ObservableError.subscribeActual(ObservableError.java:37)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner(ObservableFlatMap.java:162)
                                                                                     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(ObservableFlatMap.java:139)
                                                                                     at io.reactivex.internal.util.NotificationLite.accept(NotificationLite.java:246)
                                                                                     at io.reactivex.internal.operators.observable.ObservableCache$ReplayDisposable.replay(ObservableCache.java:350)
                                                                                     at io.reactivex.internal.operators.observable.ObservableCache.subscribeActual(ObservableCache.java:85)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableElementAtSingle.subscribeActual(ObservableElementAtSingle.java:37)
                                                                                     at io.reactivex.Single.subscribe(Single.java:3096)
03-08 14:47:18.324 11563-11586/com.polidea.rxandroidble.sample E/AndroidRuntime:     at io.reactivex.internal.operators.single.SingleToFlowable.subscribeActual(SingleToFlowable.java:37)
                                                                                     at io.reactivex.Flowable.subscribe(Flowable.java:13234)
                                                                                     at io.reactivex.Flowable.subscribe(Flowable.java:13180)
                                                                                     at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.onNext(FlowableFlatMap.java:163)
                                                                                     at io.reactivex.internal.operators.flowable.FlowableFromArray$ArraySubscription.fastPath(FlowableFromArray.java:134)
                                                                                     at io.reactivex.internal.operators.flowable.FlowableFromArray$BaseArraySubscription.request(FlowableFromArray.java:87)
                                                                                     at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.onSubscribe(FlowableFlatMap.java:115)
                                                                                     at io.reactivex.internal.operators.flowable.FlowableFromArray.subscribeActual(FlowableFromArray.java:37)
                                                                                     at io.reactivex.Flowable.subscribe(Flowable.java:13234)
                                                                                     at io.reactivex.Flowable.subscribe(Flowable.java:13180)
                                                                                     at io.reactivex.internal.operators.flowable.FlowableFlatMapPublisher.subscribeActual(FlowableFlatMapPublisher.java:43)
                                                                                     at io.reactivex.Flowable.subscribe(Flowable.java:13234)
                                                                                     at io.reactivex.internal.operators.flowable.FlowableElementAtSingle.subscribeActual(FlowableElementAtSingle.java:41)
                                                                                     at io.reactivex.Single.subscribe(Single.java:3096)
                                                                                     at io.reactivex.Single.subscribeWith(Single.java:3140)
                                                                                     at com.polidea.rxandroidble2.internal.operations.ConnectOperation$4.subscribe(ConnectOperation.java:144)
                                                                                     at io.reactivex.internal.operators.single.SingleCreate.subscribeActual(SingleCreate.java:39)
                                                                                     at io.reactivex.Single.subscribe(Single.java:3096)
                                                                                     at io.reactivex.internal.operators.single.SingleTimeout.subscribeActual(SingleTimeout.java:53)
                                                                                     at io.reactivex.Single.subscribe(Single.java:3096)
                                                                                     at io.reactivex.internal.operators.single.SingleDoFinally.subscribeActual(SingleDoFinally.java:46)
                                                                                     at io.reactivex.Single.subscribe(Single.java:3096)
                                                                                     at io.reactivex.Single.subscribeWith(Single.java:3140)
                                                                                     at com.polidea.rxandroidble2.internal.operations.ConnectOperation.protectedRun(ConnectOperation.java:79)
                                                                                     at com.polidea.rxandroidble2.internal.QueueOperation$1.subscribe(QueueOperation.java:41)
                                                                                     at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
                                                                                     at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
                                                                                     at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
                                                                                     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                                     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
                                                                                     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                                                                                     at java.lang.Thread.run(Thread.java:761)
                                                                                  Caused by: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from AA:BB:CC:11:22:33
                                                                                     at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter$1.apply(DisconnectionRouter.java:38)
                                                                                     at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter$1.apply(DisconnectionRouter.java:35)
                                                                                     at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:59)
                                                                                     at io.reactivex.internal.operators.observable.ObservableFilter$FilterObserver.onNext(ObservableFilter.java:52)
                                                                                     at io.reactivex.internal.operators.observable.ObservableConcatMap$ConcatMapDelayErrorObserver.drain(ObservableConcatMap.java:464)
                                                                                     at io.reactivex.internal.operators.observable.ObservableConcatMap$ConcatMapDelayErrorObserver.onSubscribe(ObservableConcatMap.java:324)
                                                                                     at io.reactivex.internal.operators.observable.ObservableFromArray.subscribeActual(ObservableFromArray.java:30)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableConcatMap.subscribeActual(ObservableConcatMap.java:54)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
03-08 14:47:18.328 11563-11586/com.polidea.rxandroidble.sample E/AndroidRuntime:     at io.reactivex.internal.operators.observable.ObservableFilter.subscribeActual(ObservableFilter.java:30)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:33)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner(ObservableFlatMap.java:162)
                                                                                     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(ObservableFlatMap.java:139)
                                                                                     at io.reactivex.internal.operators.observable.ObservableFromArray$FromArrayDisposable.run(ObservableFromArray.java:107)
                                                                                     at io.reactivex.internal.operators.observable.ObservableFromArray.subscribeActual(ObservableFromArray.java:36)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableElementAt.subscribeActual(ObservableElementAt.java:36)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableCache$CacheState.connect(ObservableCache.java:216)
                                                                                     at io.reactivex.internal.operators.observable.ObservableCache.subscribeActual(ObservableCache.java:82)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11180)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11058)
                                                                                     at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter.<init>(DisconnectionRouter.java:60)
                                                                                     at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter_Factory.get(DisconnectionRouter_Factory.java:33)
                                                                                     at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter_Factory.get(DisconnectionRouter_Factory.java:10)
                                                                                     at bleshadow.dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
                                                                                     at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback_Factory.get(RxBleGattCallback_Factory.java:33)
                                                                                     at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback_Factory.get(RxBleGattCallback_Factory.java:8)
                                                                                     at bleshadow.dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
                                                                                     at com.polidea.rxandroidble2.DaggerClientComponent$DeviceComponentImpl$ConnectionComponentImpl.connectOperation(DaggerClientComponent.java:713)
                                                                                     at com.polidea.rxandroidble2.internal.connection.ConnectorImpl$1.call(ConnectorImpl.java:56)
                                                                                     at com.polidea.rxandroidble2.internal.connection.ConnectorImpl$1.call(ConnectorImpl.java:41)
                                                                                     at io.reactivex.internal.operators.observable.ObservableDefer.subscribeActual(ObservableDefer.java:32)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableDoFinally.subscribeActual(ObservableDoFinally.java:45)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableDefer.subscribeActual(ObservableDefer.java:39)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableTakeUntil.subscribeActual(ObservableTakeUntil.java:41)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableObserveOn.subscribeActual(ObservableObserveOn.java:45)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.internal.operators.observable.ObservableDoFinally.subscribeActual(ObservableDoFinally.java:45)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11180)
                                                                                     at io.reactivex.Observable.subscribe(Observable.java:11109)
                                                                                     at com.polidea.rxandroidble2.sample.example2_connection.ConnectionExampleActivity.onConnectToggleClick(ConnectionExampleActivity.java:52)
03-08 14:47:18.328 11563-11586/com.polidea.rxandroidble.sample E/AndroidRuntime:     at com.polidea.rxandroidble2.sample.example2_connection.ConnectionExampleActivity_ViewBinding$1.doClick(ConnectionExampleActivity_ViewBinding.java:43)
                                                                                     at butterknife.internal.DebouncingOnClickListener.onClick(DebouncingOnClickListener.java:22)
                                                                                     at android.view.View.performClick(View.java:5637)
                                                                                     at android.view.View$PerformClick.run(View.java:22429)
                                                                                     at android.os.Handler.handleCallback(Handler.java:751)
                                                                                     at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                     at android.os.Looper.loop(Looper.java:154)
                                                                                     at android.app.ActivityThread.main(ActivityThread.java:6119)
                                                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
03-08 14:47:18.334 11563-11586/com.polidea.rxandroidble.sample D/Error: ERR: exClass=com.polidea.rxandroidble2.exceptions.BleDisconnectedException
03-08 14:47:18.334 11563-11586/com.polidea.rxandroidble.sample D/Error: ERR: exMsg=Disconnected from AA:BB:CC:11:22:33
03-08 14:47:18.334 11563-11586/com.polidea.rxandroidble.sample D/Error: ERR: file=DisconnectionRouter.java
03-08 14:47:18.334 11563-11586/com.polidea.rxandroidble.sample D/Error: ERR: class=com.polidea.rxandroidble2.internal.connection.DisconnectionRouter$1
03-08 14:47:18.334 11563-11586/com.polidea.rxandroidble.sample D/Error: ERR: method=apply line=38
03-08 14:47:18.335 11563-11586/com.polidea.rxandroidble.sample D/Error: ERR: stack=io.reactivex.exceptions.UndeliverableException: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from AA:BB:CC:11:22:33
                                                                            at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:366)
                                                                            at io.reactivex.internal.operators.observable.ObservableUnsubscribeOn$UnsubscribeObserver.onError(ObservableUnsubscribeOn.java:67)
                                                                            at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onError(ObservableSubscribeOn.java:63)
                                                                            at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.tryOnError(ObservableCreate.java:85)
                                                                            at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onError(ObservableCreate.java:73)
                                                                            at com.polidea.rxandroidble2.internal.util.DisposableUtil$3.onError(DisposableUtil.java:60)
                                                                            at io.reactivex.internal.operators.single.SingleDoFinally$DoFinallyObserver.onError(SingleDoFinally.java:81)
                                                                            at io.reactivex.internal.operators.single.SingleTimeout$TimeoutMainObserver.onError(SingleTimeout.java:142)
                                                                            at io.reactivex.internal.operators.single.SingleCreate$Emitter.tryOnError(SingleCreate.java:95)
                                                                            at io.reactivex.internal.operators.single.SingleCreate$Emitter.onError(SingleCreate.java:81)
                                                                            at com.polidea.rxandroidble2.internal.util.DisposableUtil$1.onError(DisposableUtil.java:24)
                                                                            at io.reactivex.internal.operators.flowable.FlowableElementAtSingle$ElementAtSubscriber.onError(FlowableElementAtSingle.java:101)
                                                                            at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.checkTerminate(FlowableFlatMap.java:566)
                                                                            at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.drainLoop(FlowableFlatMap.java:374)
                                                                            at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.drain(FlowableFlatMap.java:366)
                                                                            at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.innerError(FlowableFlatMap.java:605)
                                                                            at io.reactivex.internal.operators.flowable.FlowableFlatMap$InnerSubscriber.onError(FlowableFlatMap.java:668)
                                                                            at io.reactivex.internal.operators.single.SingleToFlowable$SingleToFlowableObserver.onError(SingleToFlowable.java:68)
                                                                            at io.reactivex.internal.operators.observable.ObservableElementAtSingle$ElementAtObserver.onError(ObservableElementAtSingle.java:104)
                                                                            at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495)
                                                                            at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331)
                                                                            at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323)
                                                                            at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:571)
                                                                            at io.reactivex.internal.disposables.EmptyDisposable.error(EmptyDisposable.java:63)
                                                                            at io.reactivex.internal.operators.observable.ObservableError.subscribeActual(ObservableError.java:37)
                                                                            at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                            at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner(ObservableFlatMap.java:162)
                                                                            at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(ObservableFlatMap.java:139)
                                                                            at io.reactivex.internal.util.NotificationLite.accept(NotificationLite.java:246)
                                                                            at io.reactivex.internal.operators.observable.ObservableCache$ReplayDisposable.replay(ObservableCache.java:350)
                                                                            at io.reactivex.internal.operators.observable.ObservableCache.subscribeActual(ObservableCache.java:85)
                                                                            at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                            at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55)
                                                                            at io.reactivex.Observable.subscribe(Observable.java:11194)
                                                                            at io.reactivex.internal.operators.observable.ObservableElementAtSingle.subscribeActual(ObservableElementAtSingle.java:37)
                                                                            at io.reactivex.Single.subscribe(Single.java:3096)
                                                                            at io.reactivex.internal.operators.single.SingleToFlowable.subscribeActual(SingleToFlowable.java:37)
                                                                        	at io.reactivex.Flowable.subscribe(Fl
03-08 14:47:18.335 11563-11586/com.polidea.rxandroidble.sample D/Error: ERR: TOTAL BYTES WRITTEN: 25616
@dariuszseweryn
Copy link
Owner

Mentioning @uKL

@eimermusic
Copy link

Then I am not alone.
I was just about to paste an almost identical stacktrace.

I too have a call to connect again directly from my onConnectionFailure handler because I generally want to re-establish the connection ASAP.

E.g. this is the meat of my connection method.

val connectionSubscription = device.establishConnection(false)
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnDispose({onDisposeConnectionSubscription(device)})
                    .subscribe({ onConnectionReceived(device, it) }, { onConnectionFailure(device, it) })

Side note: doOnDispose does not appear to be called in the way doOnUnsubscribe is called in rx1 land. It is in fact not called at all for me, but I have also not looked enough at the RXJava guides to know if it should be.

Just in case my trace adds some value, here it is:

03-08 14:56:49.556 7264-7480 E/AndroidRuntime: FATAL EXCEPTION: pool-6-thread-1
                                               Process: com.example.rxble, PID: 7264
                                               io.reactivex.exceptions.UndeliverableException: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from 54:6C:0E:7B:3E:98
                                                   at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
                                                   at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:573)
                                                   at io.reactivex.internal.disposables.EmptyDisposable.error(EmptyDisposable.java:63)
                                                   at io.reactivex.internal.operators.observable.ObservableError.subscribeActual(ObservableError.java:37)
                                                   at io.reactivex.Observable.subscribe(Observable.java:11442)
                                                   at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner(ObservableFlatMap.java:162)
                                                   at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(ObservableFlatMap.java:139)
                                                   at io.reactivex.internal.util.NotificationLite.accept(NotificationLite.java:246)
                                                   at io.reactivex.internal.operators.observable.ObservableCache$ReplayDisposable.replay(ObservableCache.java:350)
                                                   at io.reactivex.internal.operators.observable.ObservableCache.subscribeActual(ObservableCache.java:85)
                                                   at io.reactivex.Observable.subscribe(Observable.java:11442)
                                                   at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55)
                                                   at io.reactivex.Observable.subscribe(Observable.java:11442)
                                                   at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner(ObservableFlatMap.java:162)
                                                   at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(ObservableFlatMap.java:139)
                                                   at io.reactivex.internal.operators.observable.ObservableFromArray$FromArrayDisposable.run(ObservableFromArray.java:107)
                                                   at io.reactivex.internal.operators.observable.ObservableFromArray.subscribeActual(ObservableFromArray.java:36)
                                                   at io.reactivex.Observable.subscribe(Observable.java:11442)
                                                   at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55)
                                                   at io.reactivex.Observable.subscribe(Observable.java:11442)
                                                   at io.reactivex.internal.operators.observable.ObservableObserveOn.subscribeActual(ObservableObserveOn.java:45)
                                                   at io.reactivex.Observable.subscribe(Observable.java:11442)
                                                   at io.reactivex.internal.operators.observable.ObservableRetryPredicate$RepeatObserver.subscribeNext(ObservableRetryPredicate.java:111)
                                                   at io.reactivex.internal.operators.observable.ObservableRetryPredicate$RepeatObserver.onError(ObservableRetryPredicate.java:92)
                                                   at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.checkTerminated(ObservableObserveOn.java:276)
                                                   at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:172)
                                                   at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252)
                                                   at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run(ExecutorScheduler.java:261)
                                                   at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.run(ExecutorScheduler.java:226)
                                                   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
                                                   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                                                   at java.lang.Thread.run(Thread.java:762)
                                                Caused by: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from 54:6C:0E:7B:3E:98
                                                   at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback$2.onConnectionStateChange(RxBleGattCallback.java:77)
                                                   at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:228)
                                                   at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70)
                                                   at android.os.Binder.execTransact(Binder.java:573)

@dariuszseweryn dariuszseweryn added the bug Bug that is caused by the library label Mar 8, 2018
@dariuszseweryn
Copy link
Owner

Could you two write a minimal code that would reproduce the error?

@eimermusic
Copy link

Maybe. I might try taking the project sample app and modifying it.

For me the crashes are not reliably reproducible. It most reliably happens when I:
• Simply rip the battery out of the BLE device.
• Wait for the eternity that Android seems to prefer before noticing this.
• The app will not try to connect, fail, connect, fail...
• Re-insert battery, powering up the device.
• The re-establishing of the connection at this point can sometimes work just fine, but more often than not it will throw this exception when calling establishConnection.

Re-inserting the battery before the phone notices the lost connection can also cause some very "interesting" behavior.

@uKL
Copy link
Collaborator

uKL commented Mar 9, 2018

Thanks, I'll follow up probably early next week. :)

@uKL
Copy link
Collaborator

uKL commented Mar 12, 2018

Hey @guillaumebo, first thing. Here's a morning read for you ReactiveX/RxJava#4811 There is a slight difference between doOnDispose and doFinally. I suppose you should use the latter.

UndeliverableException mentioned in the log comes from a fact that in RxJava2 you cannot emit errors when the subscriber is no longer subscribed. This may be either an issue in the library or in your code - I don't know yet, I'll update this issue.

@GuillaumeBourge
Copy link
Contributor Author

Thanks @uKL , I had already asked myself the question of the difference between these two.
The logs paste here came from the (not modified) sample ap. In my app i have the same result. So maybe the implementation in the sample app and in my app are wrong ? i can not understand where the wrong call comes from...

@uKL
Copy link
Collaborator

uKL commented Mar 12, 2018

I've seen something similar coming from the inside of the library, I'll try to investigate it.

@streetsofboston
Copy link

We've seen these BleDisconnectedExceptions wrapped in UndeliverableException in our projects for a while now, when using RxJava2.

This happens when you dispose of the subscription while a disconnect takes place.
The RxAndroidBle code delivers this exception just before your code disposes of the subscription but was about to reach your just-disposed error-handler just after your code disposes of it.

We worked around this by registering an uncaught-exception handler by calling RxJavaPlugins.setErrorHandler and handling the UndeliverableException appropriately. The handler we used just logged the uncaught-exception, but did not let the app crash.

@uKL
Copy link
Collaborator

uKL commented Mar 12, 2018

You've got the point. However, we'd like to manage the error propagation to verify if emitted errors are in fact ignorable or this was a mistake. We'll issue an update with a fix soon.

uKL added a commit that referenced this issue Mar 12, 2018
…l changes to emitter based observers were required.
uKL added a commit that referenced this issue Mar 13, 2018
…l changes to emitter based observers were required. (#389)
@uKL uKL closed this as completed Mar 14, 2018
@NitroG42
Copy link

NitroG42 commented Mar 14, 2018

I tried the 1.5.0 release and 1.6.0-SNAPSHOT and still get this issue:
This issue happens when the device is forcely rebooted. Is there any way to get around without settings a whole error handler ? (See post below for full error)

@streetsofboston
Copy link

streetsofboston commented Mar 14, 2018

@NitroG42 If you subscribe or observe on a different scheduler than the one that is used by the RxAndroidBle connection-handler, you still can get this error. After the fix of this issue, the error may be delivered properly all the way up to your code that calls the RxAndroidBle methods, but if you then continue your Rx-chain on a different Scheduler, you still may wind up with the UndeliverableException.

@NitroG42
Copy link

I'm not using others schedulers unfortunatelly... Here's my code, It might help ! (or not):

connectionObs = RxClientHolder.rxBleClient.getBleDevice(device.macAdress)
                .establishConnection(true)
                .retryWhen { errorNotification ->
                    errorNotification.doOnNext { Timber.e("error during connection, retrying...") }
                        .delay(2, TimeUnit.SECONDS)
                }
                .compose(ConnectionSharingAdapter())
                .doOnNext { DeviceEvents.connectionStatus.onNext(ConnectionStatus.CONNECTED) }


            connectDisposable?.dispose()
            connectDisposable = connectionObs!!.flatMap { rxBleConnection ->
                val monitoringData = device.monitoringData!!
                val configData = device.configData!!
                Single.zip(
                    listOf(
                        rxBleConnection.readCharacteristic(Device3UUID.MONITORING.CHAR_TEMP).doOnSuccess(
                            monitoringData::updateTemp
                        ),
                        rxBleConnection.readCharacteristic(Device3UUID.MONITORING.CHAR_BATT).doOnSuccess(
                            monitoringData::updateBatt
                        ),
                        rxBleConnection.readCharacteristic(Device3UUID.MONITORING.CHAR_USB).doOnSuccess(
                            monitoringData::updateUsb
                        ),
                        rxBleConnection.readCharacteristic(Device3UUID.CONFIG.CHAR_LED).doOnSuccess(
                            configData::updateLed
                        )
                    ), { raw: Array<Any> ->

                    }).flatMapObservable {
                    Observable.combineLatest(
                        listOf(
                            rxBleConnection.setupNotification(Device3UUID.MONITORING.CHAR_BATT).flatMap { it }.doOnNext(
                                monitoringData::updateBatt
                            ),
                            rxBleConnection.setupNotification(Device3UUID.MONITORING.CHAR_TEMP).flatMap { it }.doOnNext(
                                monitoringData::updateTemp
                            ),
                            rxBleConnection.setupNotification(Device3UUID.MONITORING.CHAR_USB).flatMap { it }.doOnNext(
                                monitoringData::updateUsb
                            ),
                            rxBleConnection.setupNotification(Device3UUID.CONFIG.CHAR_LED).flatMap { it }.doOnNext(
                                configData::updateLed
                            )
                        ), { raw: Array<Any> ->
                            Timber.d("received notification")
                            raw
                        })
                }
            }
                .doAfterTerminate { DeviceEvents.connectionStatus.onNext(ConnectionStatus.DISCONNECTED) }
                .subscribe({
                }, {
                    Timber.e(it, "onErrorConnection")
                })

The issue occurs because I plug my ble device (with usb), and it's triggers a forced reboot, then the crash occurs.
I understand that the device shouldn't do that, but I think the establishConnection should trigger onError and not crash like this (if possible). My code might be wrong too.

@NitroG42
Copy link

NitroG42 commented Mar 14, 2018

Here's the log with the exception :

03-14 17:09:03.491 4376-4656/fr.openium.Device3app V/RxBle#ServiceDiscoveryOperation: Preparing services description
03-14 17:09:03.501 4376-4656/fr.openium.Device3app V/RxBle#ServiceDiscoveryOperation: --------------- ====== Printing peripheral content ====== ---------------
    PERIPHERAL ADDRESS: D5:A5:72:34:43:7E
    PERIPHERAL NAME: DW3_231A5732
    -------------------------------------------------------------------------
    Primary Service - Generic Access (00001800-0000-1000-8000-00805f9b34fb)
    Instance ID: 0
    -> Characteristics:
    	* Device Name (00002a00-0000-1000-8000-00805f9b34fb)
    	  Properties: [ READ WRITE ]
    	* Appearance (00002a01-0000-1000-8000-00805f9b34fb)
    	  Properties: [ READ ]
    	* Peripheral Preferred Connection Parameters (00002a04-0000-1000-8000-00805f9b34fb)
    	  Properties: [ READ ]
    	* Central Address Resolution (00002aa6-0000-1000-8000-00805f9b34fb)
    	  Properties: [ READ ]
    Primary Service - Generic Attribute (00001801-0000-1000-8000-00805f9b34fb)
    Instance ID: 0
    -> Characteristics:
    	* Service Changed (00002a05-0000-1000-8000-00805f9b34fb)
    	  Properties: [ INDICATE ]
    	  -> Descriptors: 
    		* Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
    Primary Service - Unknown service (0000fe59-0000-1000-8000-00805f9b34fb)
    Instance ID: 0
    -> Characteristics:
    	* Unknown characteristic (8ec90003-f315-4f60-9fb8-838830daea50)
    	  Properties: [ WRITE INDICATE ]
    	  -> Descriptors: 
    		* Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
    Primary Service - Device Information (0000180a-0000-1000-8000-00805f9b34fb)
    Instance ID: 0
    -> Characteristics:
    	* Manufacturer Name String (00002a29-0000-1000-8000-00805f9b34fb)
    	  Properties: [ READ ]
    Primary Service - Unknown service (1b0d1200-a720-f7e9-46b6-31b601c4fca1)
    Instance ID: 0
    -> Characteristics:
    	* Unknown characteristic (1b0d1201-a720-f7e9-46b6-31b601c4fca1)
    	  Properties: [ READ NOTIFY ]
    	  -> Descriptors: 
    		* Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
    		* Characteristic User Description (00002901-0000-1000-8000-00805f9b34fb)
    	* Unknown characteristic (1b0d1202-a720-f7e9-46b6-31b601c4fca1)
    	  Properties: [ READ NOTIFY ]
    	  -> Descriptors: 
    		* Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
    		* Characteristic User Description (00002901-0000-1000-8000-00805f9b34fb)
    	* Unknown characteristic (1b0d1203-a720-f7e9-46b6-31b601c4fca1)
    	  Properties: [ READ NOTIFY ]
    	  -> Descriptors: 
    		* Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
    		* Characteristic User Description (00002901-0000-1000-8000-00805f9b34fb)
    	* Unknown characteristic (1b0d1204-a720-f7e9-46b6-31b601c4fca1)
    	  Properties: [ READ NOTIFY ]
    	  -> Descriptors: 
    		* Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
    		* Characteristic User Description (00002901-0000-1000-8000-00805f9b34fb)
    	* Unknown characteristic (1b0d1205-a720-f7e9-46b6-31b601c4fca1)
    	  Properties: [ READ NOTIFY ]
    	  -> Descriptors: 
    		* Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
    		* Characteristic User Description (00002901-0000-1000-8000-00805f9b34fb)
    	* Unknown characteristic (1b0d1206-a720-f7e9-46b6-31b601c4fca1)
    	  Properties: [ READ NOTIFY ]
    	  -> Descriptors: 
    		* Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
    		* Characteristic User Description (00002901-0000-1000-8000-00805f9b34fb)
    	* Unknown characteristic (1b0d1207-a720-f7e9-46b6-31b601c4fca1)
    	  Properties: [ READ NOTIFY ]
    	  -> Descriptors: 
    		* Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
    		* Characteristic User Description (00002901-0000-1000-8000-00805f9b34fb)
    	* Unknown characteristic (1b0d1208-a720-f7e9-46b6-31b601c4fca1)
    	  Properties: [ READ ]
    	  -> Descriptors: 
    		* Characteristic User Description (00002901-0000-1000-8000-00805f9b34fb)
    Primary Service - Unknown service (1b0d1400-a720-f7e9-46b6-31b601c4fca1)
    Instance ID: 0
    -> Characteristics:
    	* Unknown characteristic (1b0d1401-a720-f7e9-46b6-31b601c4fca1)
    	  Properties: [ READ WRITE NOTIFY ]
    	  -> Descriptors: 
    		* Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
    		* Characteristic User Description (00002901-0000-1000-8000-00805f9b34fb)
    	* Unknown characteristic (1b0d1402-a720-f7e9-46b6-31b601c4fca1)
    	  Properties: [ READ ]
    	  -> Descriptors: 
    		* Characteristic User Description (00002901-0000-1000-8000-00805f9b34fb)
    	* Unknown characteristic (1b0d1403-a720-f7e9-46b6-31b601c4fca1)
    	  Properties: [ WRITE NOTIFY ]
    	  -> Descriptors: 
    		* Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
    		* Characteristic User Description (00002901-0000-1000-8000-00805f9b34fb)
    	* Unknown characteristic (1b0d1404-a720-f7e9-46b6-31b601c4fca1)
    	  Properties: [ READ WRITE NOTIFY ]
    	  -> Descriptors: 
    		* Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
    		* Characteristic User Description (00002901-0000-1000-8000-00805f9b34fb)
    --------------- ====== Finished peripheral content ====== ---------------
03-14 17:09:03.501 4376-4656/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: QUEUED   CharacteristicReadOperation(75548787)
    QUEUED   CharacteristicReadOperation(64656176)
03-14 17:09:03.501 4376-4402/fr.openium.Device3app D/BluetoothGatt: onClientConnParamsChanged() - Device=D5:A5:72:34:43:7E interval=39 status=0
03-14 17:09:03.501 4376-4656/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: QUEUED   CharacteristicReadOperation(67730345)
    QUEUED   CharacteristicReadOperation(158160174)
03-14 17:09:03.511 4376-5682/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: FINISHED ServiceDiscoveryOperation(6507746) in 1623 ms
    STARTED  CharacteristicReadOperation(75548787)
03-14 17:09:03.601 4376-4517/fr.openium.Device3app D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=1b0d1202-a720-f7e9-46b6-31b601c4fca1 status=0
03-14 17:09:03.601 4376-4656/fr.openium.Device3app D/MonitoringData: update temp -5
03-14 17:09:03.621 4376-5682/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: FINISHED CharacteristicReadOperation(75548787) in 110 ms
    STARTED  CharacteristicReadOperation(64656176)
03-14 17:09:03.701 4376-4499/fr.openium.Device3app D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=1b0d1203-a720-f7e9-46b6-31b601c4fca1 status=0
03-14 17:09:03.701 4376-4656/fr.openium.Device3app D/MonitoringData: update batt 21893
03-14 17:09:03.721 4376-5682/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: FINISHED CharacteristicReadOperation(64656176) in 97 ms
    STARTED  CharacteristicReadOperation(67730345)
03-14 17:09:03.801 4376-4555/fr.openium.Device3app D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=1b0d1206-a720-f7e9-46b6-31b601c4fca1 status=0
03-14 17:09:03.801 4376-4656/fr.openium.Device3app D/MonitoringData: update usb false
03-14 17:09:03.821 4376-5682/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: FINISHED CharacteristicReadOperation(67730345) in 100 ms
    STARTED  CharacteristicReadOperation(158160174)
03-14 17:09:03.891 4376-4523/fr.openium.Device3app D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=1b0d1404-a720-f7e9-46b6-31b601c4fca1 status=0
03-14 17:09:03.901 4376-4656/fr.openium.Device3app D/ConfigData: update led false
03-14 17:09:03.911 4376-4656/fr.openium.Device3app D/BluetoothGatt: setCharacteristicNotification() - uuid: 1b0d1203-a720-f7e9-46b6-31b601c4fca1 enable: true
03-14 17:09:03.921 4376-4656/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: QUEUED   DescriptorWriteOperation(117282362)
03-14 17:09:03.921 4376-4656/fr.openium.Device3app D/BluetoothGatt: setCharacteristicNotification() - uuid: 1b0d1202-a720-f7e9-46b6-31b601c4fca1 enable: true
03-14 17:09:03.931 4376-4656/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: QUEUED   DescriptorWriteOperation(49387592)
03-14 17:09:03.931 4376-4656/fr.openium.Device3app D/BluetoothGatt: setCharacteristicNotification() - uuid: 1b0d1206-a720-f7e9-46b6-31b601c4fca1 enable: true
03-14 17:09:03.931 4376-4656/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: QUEUED   DescriptorWriteOperation(203348998)
03-14 17:09:03.941 4376-4656/fr.openium.Device3app D/BluetoothGatt: setCharacteristicNotification() - uuid: 1b0d1404-a720-f7e9-46b6-31b601c4fca1 enable: true
03-14 17:09:03.941 4376-4656/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: QUEUED   DescriptorWriteOperation(78377204)
03-14 17:09:03.941 4376-5682/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: FINISHED CharacteristicReadOperation(158160174) in 122 ms
    STARTED  DescriptorWriteOperation(117282362)
03-14 17:09:04.041 4376-4517/fr.openium.Device3app D/RxBle#BluetoothGatt: onDescriptorWrite descriptor=00002902-0000-1000-8000-00805f9b34fb status=0
03-14 17:09:04.041 4376-5682/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: FINISHED DescriptorWriteOperation(117282362) in 101 ms
03-14 17:09:04.051 4376-5682/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: STARTED  DescriptorWriteOperation(49387592)
03-14 17:09:04.141 4376-4538/fr.openium.Device3app D/RxBle#BluetoothGatt: onDescriptorWrite descriptor=00002902-0000-1000-8000-00805f9b34fb status=0
03-14 17:09:04.141 4376-5682/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: FINISHED DescriptorWriteOperation(49387592) in 94 ms
    STARTED  DescriptorWriteOperation(203348998)
03-14 17:09:04.241 4376-4499/fr.openium.Device3app D/RxBle#BluetoothGatt: onDescriptorWrite descriptor=00002902-0000-1000-8000-00805f9b34fb status=0
03-14 17:09:04.241 4376-5682/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: FINISHED DescriptorWriteOperation(203348998) in 96 ms
    STARTED  DescriptorWriteOperation(78377204)
03-14 17:09:04.331 4376-4393/fr.openium.Device3app D/RxBle#BluetoothGatt: onDescriptorWrite descriptor=00002902-0000-1000-8000-00805f9b34fb status=0
03-14 17:09:04.341 4376-5682/fr.openium.Device3app D/RxBle#ConnectionOperationQueue: FINISHED DescriptorWriteOperation(78377204) in 96 ms
03-14 17:09:06.841 4376-4402/fr.openium.Device3app D/BluetoothGatt: onClientConnParamsChanged() - Device=D5:A5:72:34:43:7E interval=24 status=0
03-14 17:09:07.811 4376-4538/fr.openium.Device3app D/BluetoothGatt: onClientConnectionState() - status=8 clientIf=6 device=D5:A5:72:34:43:7E
03-14 17:09:07.821 4376-4538/fr.openium.Device3app D/RxBle#BluetoothGatt: onConnectionStateChange newState=0 status=8
03-14 17:09:07.821 4376-4538/fr.openium.Device3app I/RxBle#ConnectionOperationQueue: Connection operations queue to be terminated (D5:A5:72:34:43:7E)
03-14 17:09:07.821 4376-5682/fr.openium.Device3app D/RxBle#Executors$RunnableAdapter: Terminated.
03-14 17:09:07.821 4376-4538/fr.openium.Device3app E/DeviceService$connect: error during connection, retrying...
03-14 17:09:07.831 4376-4538/fr.openium.Device3app W/System.err: io.reactivex.exceptions.UndeliverableException: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from D5:A5:72:34:43:7E
03-14 17:09:07.831 4376-4538/fr.openium.Device3app W/System.err:     at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
03-14 17:09:07.831 4376-4538/fr.openium.Device3app W/System.err:     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:310)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.dispose(ObservableObserveOn.java:146)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.disposables.SequentialDisposable.dispose(SequentialDisposable.java:73)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.observers.LambdaObserver.dispose(LambdaObserver.java:100)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.disposables.SerialDisposable.dispose(SerialDisposable.java:81)
        at com.polidea.rxandroidble2.internal.connection.MtuWatcher.onConnectionUnsubscribed(MtuWatcher.java:39)
        at com.polidea.rxandroidble2.internal.connection.ConnectorImpl$1$1.run(ConnectorImpl.java:71)
        at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.runFinally(ObservableDoFinally.java:144)
        at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.onError(ObservableDoFinally.java:88)
        at io.reactivex.internal.observers.DisposableLambdaObserver.onError(DisposableLambdaObserver.java:64)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:571)
03-14 17:09:07.831 4376-4538/fr.openium.Device3app W/System.err:     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:571)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331)
03-14 17:09:07.831 4376-4538/fr.openium.Device3app W/System.err:     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:571)
        at io.reactivex.internal.disposables.EmptyDisposable.error(EmptyDisposable.java:63)
03-14 17:09:07.831 4376-4538/fr.openium.Device3app W/System.err:     at io.reactivex.internal.operators.observable.ObservableError.subscribeActual(ObservableError.java:37)
        at io.reactivex.Observable.subscribe(Observable.java:11442)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner(ObservableFlatMap.java:162)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(ObservableFlatMap.java:139)
        at io.reactivex.internal.util.NotificationLite.accept(NotificationLite.java:246)
        at io.reactivex.internal.operators.observable.ObservableCache$ReplayDisposable.replay(ObservableCache.java:350)
        at io.reactivex.internal.operators.observable.ObservableCache$CacheState.onNext(ObservableCache.java:225)
        at io.reactivex.internal.operators.observable.ObservableElementAt$ElementAtObserver.onNext(ObservableElementAt.java:87)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.tryEmit(ObservableFlatMap.java:262)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onNext(ObservableFlatMap.java:559)
        at com.jakewharton.rxrelay2.PublishRelay$PublishDisposable.onNext(PublishRelay.java:176)
        at com.jakewharton.rxrelay2.PublishRelay.accept(PublishRelay.java:141)
03-14 17:09:07.831 4376-4538/fr.openium.Device3app W/System.err:     at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter.onDisconnectedException(DisconnectionRouter.java:86)
        at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback$2.onConnectionStateChange(RxBleGattCallback.java:77)
        at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:228)
        at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70)
        at android.os.Binder.execTransact(Binder.java:453)
    Caused by: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from D5:A5:72:34:43:7E
    	... 4 more
03-14 17:09:07.841 4376-4538/fr.openium.Device3app E/AndroidRuntime: FATAL EXCEPTION: Binder_7
    Process: fr.openium.Device3app, PID: 4376
    io.reactivex.exceptions.UndeliverableException: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from D5:A5:72:34:43:7E
        at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:310)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.dispose(ObservableObserveOn.java:146)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.disposables.SequentialDisposable.dispose(SequentialDisposable.java:73)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.observers.LambdaObserver.dispose(LambdaObserver.java:100)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.disposables.SerialDisposable.dispose(SerialDisposable.java:81)
        at com.polidea.rxandroidble2.internal.connection.MtuWatcher.onConnectionUnsubscribed(MtuWatcher.java:39)
        at com.polidea.rxandroidble2.internal.connection.ConnectorImpl$1$1.run(ConnectorImpl.java:71)
        at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.runFinally(ObservableDoFinally.java:144)
        at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.onError(ObservableDoFinally.java:88)
        at io.reactivex.internal.observers.DisposableLambdaObserver.onError(DisposableLambdaObserver.java:64)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:571)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:571)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:571)
        at io.reactivex.internal.disposables.EmptyDisposable.error(EmptyDisposable.java:63)
        at io.reactivex.internal.operators.observable.ObservableError.subscribeActual(ObservableError.java:37)
        at io.reactivex.Observable.subscribe(Observable.java:11442)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner(ObservableFlatMap.java:162)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(ObservableFlatMap.java:139)
        at io.reactivex.internal.util.NotificationLite.accept(NotificationLite.java:246)
        at io.reactivex.internal.operators.observable.ObservableCache$ReplayDisposable.replay(ObservableCache.java:350)
        at io.reactivex.internal.operators.observable.ObservableCache$CacheState.onNext(ObservableCache.java:225)
        at io.reactivex.internal.operators.observable.ObservableElementAt$ElementAtObserver.onNext(ObservableElementAt.java:87)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.tryEmit(ObservableFlatMap.java:262)
    	at io.reactivex.internal.o

@uKL uKL reopened this Mar 14, 2018
@uKL
Copy link
Collaborator

uKL commented Mar 15, 2018

@NitroG42 Does it happen everytime you process this scenario? What is the device you are testing on?

@NitroG42
Copy link

It happens randomly when the device is disconnected, either by usb or sometime randomly when we are connected to it.
The device is a custom made by a company we works with. The chip is a Nordic one.
If worked around by catching the error with the RxJavaPlugin, sending a value in an observable to know it happens and restart connection with a delay of 5 seconds.

uKL added a commit that referenced this issue Mar 15, 2018
…er. (#393)

* [#383] Trying to fix undeliverable exception when disposing MTU watcher.

* Retry only on MTU related errors.
@uKL
Copy link
Collaborator

uKL commented Mar 15, 2018

@NitroG42 Snapshot 1.6.0 is rolling (will be available soon). Could you try it out?

@NitroG42
Copy link

I will try, I'll update the thread when I have news.

@NitroG42
Copy link

NitroG42 commented Mar 15, 2018

I still got the issue, I can trigger it just by disposing my connectDisposable (see above, it's the result of the subscribe that connect using ConnectionSharingAdapter, and readChara):

03-15 16:20:12.849 22277-22277/fr.openium.device3app D/deviceService: service stopped
03-15 16:20:12.849 22277-22305/fr.openium.device3app D/RxBle#ClientOperationQueue: QUEUED   DisconnectOperation(35906593)
03-15 16:20:12.849 22277-22277/fr.openium.device3app D/BluetoothGatt: setCharacteristicNotification() - uuid: 1b0d1203-a720-f7e9-46b6-31b601c4fca1 enable: false
03-15 16:20:12.849 22277-22305/fr.openium.device3app I/RxBle#ConnectionOperationQueue: Connection operations queue to be terminated (F1:13:65:7E:30:C3)
03-15 16:20:12.849 22277-22304/fr.openium.device3app D/RxBle#Executors$RunnableAdapter: Terminated.
03-15 16:20:12.849 22277-22297/fr.openium.device3app D/RxBle#ClientOperationQueue: STARTED  DisconnectOperation(35906593)
03-15 16:20:12.849 22277-22306/fr.openium.device3app D/BluetoothManager: getConnectionState()
03-15 16:20:12.849 22277-22306/fr.openium.device3app D/BluetoothManager: getConnectedDevices
03-15 16:20:12.859 22277-22277/fr.openium.device3app D/RxBle#ConnectionOperationQueue: QUEUED   DescriptorWriteOperation(726687814)
03-15 16:20:12.859 22277-22306/fr.openium.device3app D/BluetoothGatt: cancelOpen() - device: F1:13:65:7E:30:C3
03-15 16:20:12.859 22277-22277/fr.openium.device3app D/BluetoothGatt: setCharacteristicNotification() - uuid: 1b0d1202-a720-f7e9-46b6-31b601c4fca1 enable: false
03-15 16:20:12.869 22277-22292/fr.openium.device3app D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=F1:13:65:7E:30:C3
03-15 16:20:12.869 22277-22292/fr.openium.device3app D/RxBle#BluetoothGatt: onConnectionStateChange newState=0 status=0
03-15 16:20:12.869 22277-22277/fr.openium.device3app D/BluetoothGatt: setCharacteristicNotification() - uuid: 1b0d1206-a720-f7e9-46b6-31b601c4fca1 enable: false
03-15 16:20:12.869 22277-22292/fr.openium.device3app D/BluetoothGatt: setCharacteristicNotification() - uuid: 1b0d1204-a720-f7e9-46b6-31b601c4fca1 enable: false
03-15 16:20:12.869 22277-22292/fr.openium.device3app D/BluetoothGatt: setCharacteristicNotification() - uuid: 1b0d1205-a720-f7e9-46b6-31b601c4fca1 enable: false
03-15 16:20:12.869 22277-22277/fr.openium.device3app E/device3Api$init: rx undeliverable error disconnected
    io.reactivex.exceptions.UndeliverableException: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from F1:13:65:7E:30:C3
        at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:310)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.operators.observable.ObservableReplay$ReplayObserver.dispose(ObservableReplay.java:276)
        at io.reactivex.disposables.CompositeDisposable.dispose(CompositeDisposable.java:217)
        at io.reactivex.disposables.CompositeDisposable.dispose(CompositeDisposable.java:80)
        at io.reactivex.internal.operators.observable.ObservableRefCount$DisposeTask.run(ObservableRefCount.java:219)
        at io.reactivex.disposables.RunnableDisposable.onDisposed(RunnableDisposable.java:30)
        at io.reactivex.disposables.RunnableDisposable.onDisposed(RunnableDisposable.java:20)
        at io.reactivex.disposables.ReferenceDisposable.dispose(ReferenceDisposable.java:43)
        at io.reactivex.internal.operators.observable.ObservableRefCount$ConnectionObserver.dispose(ObservableRefCount.java:151)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
03-15 16:20:12.879 22277-22277/fr.openium.device3app E/device3Api$init:     at io.reactivex.internal.disposables.SequentialDisposable.dispose(SequentialDisposable.java:73)
03-15 16:20:12.879 22277-22277/fr.openium.device3app E/device3Api$init:     at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.dispose(ObservableFlatMap.java:583)
03-15 16:20:12.879 22277-22277/fr.openium.device3app E/device3Api$init:     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.disposeAll(ObservableFlatMap.java:509)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:307)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.disposeAll(ObservableFlatMap.java:503)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:307)
03-15 16:20:12.879 22277-22305/fr.openium.device3app D/RxBle#MtuWatcher: An error received when listening to MTU changes.
    com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from F1:13:65:7E:30:C3
        at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback$2.onConnectionStateChange(RxBleGattCallback.java:77)
        at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:186)
        at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70)
        at android.os.Binder.execTransact(Binder.java:446)
03-15 16:20:12.879 22277-22277/fr.openium.device3app E/device3Api$init:     at io.reactivex.internal.operators.observable.ObservableDoOnEach$DoOnEachObserver.dispose(ObservableDoOnEach.java:80)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.operators.observable.ObservableCombineLatest$CombinerObserver.dispose(ObservableCombineLatest.java:321)
        at io.reactivex.internal.operators.observable.ObservableCombineLatest$LatestCoordinator.cancelSources(ObservableCombineLatest.java:140)
        at io.reactivex.internal.operators.observable.ObservableCombineLatest$LatestCoordinator.dispose(ObservableCombineLatest.java:126)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.dispose(ObservableFlatMap.java:583)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.disposeAll(ObservableFlatMap.java:509)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:307)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.dispose(ObservableFlatMap.java:583)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.disposeAll(ObservableFlatMap.java:509)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:307)
        at io.reactivex.internal.observers.DisposableLambdaObserver.dispose(DisposableLambdaObserver.java:86)
        at io.reactivex.internal.operators.observable.ObservableDoOnEach$DoOnEachObserver.dispose(ObservableDoOnEach.java:80)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.observers.LambdaObserver.dispose(LambdaObserver.java:100)
        at io.reactivex.disposables.CompositeDisposable.dispose(CompositeDisposable.java:217)
        at io.reactivex.disposables.CompositeDisposable.dispose(CompositeDisposable.java:80)
        at fr.openium.device3lib.service.deviceService.onDestroy(deviceService.kt:79)
        at android.app.ActivityThread.handleStopService(ActivityThread.java:3974)
        at android.app.ActivityThread.access$2400(ActivityThread.java:219)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1838)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:145)
        at android.app.ActivityThread.main(ActivityThread.java:6939)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
    Caused by: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from F1:13:65:7E:30:C3
        at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback$2.onConnectionStateChange(RxBleGattCallback.java:77)
        at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:186)
        at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70)
        at android.os.Binder.execTransact(Binder.java:446)

@uKL
Copy link
Collaborator

uKL commented Mar 16, 2018

I really struggle to reproduce your issue. I've used exactly your code and it's working flawlessly. Are you able to prepare a minimum mode to reproduce the issue, so I can run it in my Android Studio? Can you also try without the ConnectionSharingAdapter?

@guillaumebo @eimermusic How about you Guys? Do you still see it?

@GuillaumeBourge
Copy link
Contributor Author

I just tried with the last 1.6 Snapshot, it's seems to work better !
i haven't get any crash following a bad disconnection. Sometime i get a
D/RxBle#MtuWatcher: An error received when listening to MTU changes. but correctly handle :)

@uKL
Copy link
Collaborator

uKL commented Mar 16, 2018

Yes, the warning is expected, I wanted to see if it is handled correctly. I'll remove/mask it before a release. Great news!

@bleeding182
Copy link
Contributor

I just encountered the same error, but with a different stack trace (I'm on version com.polidea.rxandroidble2:rxandroidble:1.5.0) It appears pretty much randomly after some connecting and disconnecting.

FATAL EXCEPTION: Binder:19392_4
 Process: com.some.project, PID: 19392
 io.reactivex.exceptions.UndeliverableException: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from EF:65:4B:9C:9F:61
	 at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:310)
	 at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.dispose(ObservableFlatMap.java:583)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.disposeAll(ObservableFlatMap.java:509)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:307)
	 at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.dispose(ObservableObserveOn.java:146)
	 at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
	 at io.reactivex.internal.disposables.SequentialDisposable.dispose(SequentialDisposable.java:73)
	 at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
	 at io.reactivex.internal.observers.LambdaObserver.dispose(LambdaObserver.java:100)
	 at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
	 at io.reactivex.disposables.SerialDisposable.dispose(SerialDisposable.java:81)
	 at com.polidea.rxandroidble2.internal.connection.MtuWatcher.onConnectionUnsubscribed(MtuWatcher.java:39)
	 at com.polidea.rxandroidble2.internal.connection.ConnectorImpl$1$1.run(ConnectorImpl.java:71)
	 at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.runFinally(ObservableDoFinally.java:144)
	 at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.onError(ObservableDoFinally.java:88)
	 at io.reactivex.internal.observers.DisposableLambdaObserver.onError(DisposableLambdaObserver.java:64)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onError(ObservableFlatMap.java:288)
	 at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.tryOnError(ObservableCreate.java:85)
	 at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onError(ObservableCreate.java:73)
	 at com.polidea.rxandroidble2.internal.serialization.FIFORunnableEntry$1.onError(FIFORunnableEntry.java:65)
	 at io.reactivex.internal.operators.observable.ObservableUnsubscribeOn$UnsubscribeObserver.onError(ObservableUnsubscribeOn.java:70)
	 at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onError(ObservableSubscribeOn.java:63)
	 at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.tryOnError(ObservableCreate.java:85)
	 at com.polidea.rxandroidble2.internal.util.DisposableUtil$3.onError(DisposableUtil.java:60)
	 at io.reactivex.internal.operators.single.SingleDoFinally$DoFinallyObserver.onError(SingleDoFinally.java:81)
	 at io.reactivex.internal.operators.single.SingleTimeout$TimeoutMainObserver.onError(SingleTimeout.java:142)
	 at io.reactivex.internal.operators.single.SingleCreate$Emitter.tryOnError(SingleCreate.java:95)
	 at com.polidea.rxandroidble2.internal.util.DisposableUtil$1.onError(DisposableUtil.java:24)
	 at io.reactivex.internal.operators.flowable.FlowableElementAtSingle$ElementAtSubscriber.onError(FlowableElementAtSingle.java:101)
	 at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.checkTerminate(FlowableFlatMap.java:566)
at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.drainLoop(FlowableFlatMap.java:374)
	 at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.drain(FlowableFlatMap.java:366)
	 at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.innerError(FlowableFlatMap.java:605)
	 at io.reactivex.internal.operators.flowable.FlowableFlatMap$InnerSubscriber.onError(FlowableFlatMap.java:668)
	 at io.reactivex.internal.operators.single.SingleToFlowable$SingleToFlowableObserver.onError(SingleToFlowable.java:68)
	 at io.reactivex.internal.operators.observable.ObservableElementAtSingle$ElementAtObserver.onError(ObservableElementAtSingle.java:104)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:571)
	 at io.reactivex.internal.disposables.EmptyDisposable.error(EmptyDisposable.java:63)
	 at io.reactivex.internal.operators.observable.ObservableError.subscribeActual(ObservableError.java:37)
	 at io.reactivex.Observable.subscribe(Observable.java:11442)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner(ObservableFlatMap.java:162)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(ObservableFlatMap.java:139)
	 at io.reactivex.internal.util.NotificationLite.accept(NotificationLite.java:246)
	 at io.reactivex.internal.operators.observable.ObservableCache$ReplayDisposable.replay(ObservableCache.java:350)
	 at io.reactivex.internal.operators.observable.ObservableCache$CacheState.onNext(ObservableCache.java:225)
	 at io.reactivex.internal.operators.observable.ObservableElementAt$ElementAtObserver.onNext(ObservableElementAt.java:87)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.tryEmit(ObservableFlatMap.java:262)
	 at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onNext(ObservableFlatMap.java:559)
	 at com.jakewharton.rxrelay2.PublishRelay$PublishDisposable.onNext(PublishRelay.java:176)
	 at com.jakewharton.rxrelay2.PublishRelay.accept(PublishRelay.java:141)
	 at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter.onDisconnectedException(DisconnectionRouter.java:86)
	 at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback$2.onConnectionStateChange(RxBleGattCallback.java:77)
	 at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:229)
	 at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70)
	 at android.os.Binder.execTransact(Binder.java:573)
  Caused by: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from EF:65:4B:9C:9F:61
	 at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback$2.onConnectionStateChange(RxBleGattCallback.java:77) 
	 at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:229) 
	 at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70) 
	 at android.os.Binder.execTransact(Binder.java:573) 

It seems to me this may be caused due to the isDisposed() check being done prematurely, and that this could be fixed by additionally moving the check into the callback (onError etc) or replacing it with tryOnError instead. At least in my specific case.

@ghost
Copy link

ghost commented Apr 3, 2018

having same issue too

E/AndroidRuntime: FATAL EXCEPTION: pool-9-thread-1
io.reactivex.exceptions.UndeliverableException: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from 44:2C:05:7A:3D:A9
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:310)
at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.dispose(ObservableObserveOn.java:146)
at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
at io.reactivex.internal.disposables.SequentialDisposable.dispose(SequentialDisposable.java:73)
at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
at io.reactivex.internal.observers.LambdaObserver.dispose(LambdaObserver.java:100)
at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
at io.reactivex.disposables.SerialDisposable.dispose(SerialDisposable.java:81)
at com.polidea.rxandroidble2.internal.connection.MtuWatcher.onConnectionUnsubscribed(MtuWatcher.java:39)
at com.polidea.rxandroidble2.internal.connection.ConnectorImpl$1$1.run(ConnectorImpl.java:71)
at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.runFinally(ObservableDoFinally.java:144)
at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.onError(ObservableDoFinally.java:88)
at io.reactivex.internal.observers.DisposableLambdaObserver.onError(DisposableLambdaObserver.java:64)
at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495)
at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331)
at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323)
at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onError(ObservableFlatMap.java:288)
at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.tryOnError(ObservableCreate.java:85)
at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onError(ObservableCreate.java:73)
at com.polidea.rxandroidble2.internal.serialization.FIFORunnableEntry$1.onError(FIFORunnableEntry.java:65)
at io.reactivex.internal.operators.observable.ObservableUnsubscribeOn$UnsubscribeObserver.onError(ObservableUnsubscribeOn.java:70)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onError(ObservableSubscribeOn.java:63)
at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.tryOnError(ObservableCreate.java:85)
at com.polidea.rxandroidble2.internal.util.DisposableUtil$3.onError(DisposableUtil.java:60)
at io.reactivex.internal.operators.single.SingleDoFinally$DoFinallyObserver.onError(SingleDoFinally.java:81)
at io.reactivex.internal.operators.single.SingleTimeout$TimeoutMainObserver.onError(SingleTimeout.java:142)
at io.reactivex.internal.operators.single.SingleCreate$Emitter.tryOnError(SingleCreate.java:95)
at com.polidea.rxandroidble2.internal.util.DisposableUtil$1.onError(DisposableUtil.java:24)
at io.reactivex.internal.operators.flowable.FlowableElementAtSingle$ElementAtSubscriber.onError(FlowableElementAtSingle.java:101)
at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.checkTerminate(FlowableFlatMap.java:566)
at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.drainLoop(FlowableFlatMap.java:374)
at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.drain(FlowableFlatMap.java:366)
at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.innerError(FlowableFlatMap.java:605)
at io.reactivex.internal.operators.flowable.FlowableFlatMap$InnerSubscriber.onError(FlowableFlatMap.java:668)
at io.reactivex.internal.operators.single.SingleToFlowab
stack=io.reactivex.exceptions.UndeliverableException:

@toaderandrei
Copy link

toaderandrei commented Apr 3, 2018

@uKL , the bug that @guillaumebo reported(below) we also have it from time to time(starting from version 1.4.1) and my goal for next sprint is to investigate this(starting today).

03-21 15:26:46.430 29682-29750/fr.test.myapp D/BluetoothGatt: cancelOpen() - device: 00:00:00:00:00:00
03-21 15:26:46.431 29682-29742/fr.test.myapp D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=00:00:00:00:00:00
03-21 15:26:46.436 29682-29753/fr.test.myapp W/System.err: io.reactivex.exceptions.UndeliverableException: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from 00:00:00:00:00:00
03-21 15:26:46.436 29682-29753/fr.test.myapp W/System.err: at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
03-21 15:26:46.436 29682-29753/fr.test.myapp W/System.err: at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onError(ObservableCreate.java:74)
03-21 15:26:46.437 29682-29753/fr.test.myapp W/System.err: at com.polidea.rxandroidble2.internal.util.QueueReleasingEmitterWrapper.onError(QueueReleasingEmitterWrapper.java:45)
03-21 15:26:46.437 29682-29753/fr.test.myapp W/System.err: at io.reactivex.internal.operators.single.SingleToObservable$SingleToObservableObserver.onError(SingleToObservable.java:65)
03-21 15:26:46.437 29682-29753/fr.test.myapp W/System.err: at io.reactivex.internal.operators.single.SingleTimeout$TimeoutMainObserver.onError(SingleTimeout.java:142)
03-21 15:26:46.437 29682-29753/fr.test.myapp W/System.err: at io.reactivex.internal.operators.single.SingleMap$MapSingleObserver.onError(SingleMap.java:69)
03-21 15:26:46.437 29682-29753/fr.test.myapp W/System.err: at io.reactivex.internal.operators.observable.ObservableElementAtSingle$ElementAtObserver.onError(ObservableElementAtSingle.java:104)
03-21 15:26:46.437 29682-29753/fr.test.myapp W/System.err: at io.reactivex.internal.observers.BasicFuseableObserver.onError(BasicFuseableObserver.java:100)
03-21 15:26:46.437 29682-29753/fr.test.myapp W/System.err: at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.checkTerminated(ObservableObserveOn.java:276)
03-21 15:26:46.437 29682-29753/fr.test.myapp W/System.err: at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:172)
03-21 15:26:46.437 29682-29753/fr.test.myapp W/System.err: at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252)
03-21 15:26:46.437 29682-29753/fr.test.myapp W/System.err: at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run(ExecutorScheduler.java:261)
03-21 15:26:46.437 29682-29753/fr.test.myapp W/System.err: at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.run(ExecutorScheduler.java:226)
03-21 15:26:46.438 29682-29753/fr.test.myapp W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
03-21 15:26:46.438 29682-29753/fr.test.myapp W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
03-21 15:26:46.438 29682-29753/fr.test.myapp W/System.err: at java.lang.Thread.run(Thread.java:761)
03-21 15:26:46.438 29682-29753/fr.test.myapp W/System.err: Caused by: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from 00:00:00:00:00:00
03-21 15:26:46.438 29682-29753/fr.test.myapp W/System.err: at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback$2.onConnectionStateChange(RxBleGattCallback.java:77)
03-21 15:26:46.438 29682-29753/fr.test.myapp W/System.err: at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:180)
03-21 15:26:46.438 29682-29753/fr.test.myapp W/System.err: at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70)
03-21 15:26:46.438 29682-29753/fr.test.myapp W/System.err: at android.os.Binder.execTransact(Binder.java:565)

@biodroid
Copy link

biodroid commented Apr 4, 2018

Hello,
I got the same undeliverable exception after deliberately disconnecting my connected object, using the 1.6.0-SNAPSHOT.

io.reactivex.exceptions.UndeliverableException: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from 00:00:00:00:00:00
        at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onError(ObservableFlatMap.java:294)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:506)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:335)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:327)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onError(ObservableFlatMap.java:292)
        at io.reactivex.internal.operators.observable.ObservableFlatMapSingle$FlatMapSingleObserver.drainLoop(ObservableFlatMapSingle.java:239)
        at io.reactivex.internal.operators.observable.ObservableFlatMapSingle$FlatMapSingleObserver.drain(ObservableFlatMapSingle.java:210)
        at io.reactivex.internal.operators.observable.ObservableFlatMapSingle$FlatMapSingleObserver.onError(ObservableFlatMapSingle.java:124)
        at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.onError(ObservableDoFinally.java:87)
        at io.reactivex.internal.operators.observable.ObservableDoOnEach$DoOnEachObserver.onError(ObservableDoOnEach.java:119)
        at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.onError(ObservableDoFinally.java:87)
        at io.reactivex.internal.operators.observable.ObservableUnsubscribeOn$UnsubscribeObserver.onError(ObservableUnsubscribeOn.java:70)
        at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onError(ObservableSubscribeOn.java:63)
        at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.onError(ObservableDoFinally.java:87)
        at io.reactivex.internal.observers.DisposableLambdaObserver.onError(DisposableLambdaObserver.java:64)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:506)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:335)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:327)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:582)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:506)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:335)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:327)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:582)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:506)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:335)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:327)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:582)
        at io.reactivex.internal.disposables.EmptyDisposable.error(EmptyDisposable.java:63)
        at io.reactivex.internal.operators.observable.ObservableError.subscribeActual(ObservableError.java:37)
        at io.reactivex.Observable.subscribe(Observable.java:12005)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner(ObservableFlatMap.java:165)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(ObservableFlatMap.java:139)
04-04 16:42:26.161 11440-11477/my.package E/MyClassTest:     at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onNext(ObservableCreate.java:67)
        at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter.notifySubscribersAboutException(DisconnectionRouter.java:125)
        at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter.onExceptionOccurred(DisconnectionRouter.java:114)
        at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter.onDisconnectedException(DisconnectionRouter.java:100)
        at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback$2.onConnectionStateChange(RxBleGattCallback.java:77)
        at android.bluetooth.BluetoothGatt$1$4.run(BluetoothGatt.java:249)
        at android.bluetooth.BluetoothGatt.runOrQueueCallback(BluetoothGatt.java:725)
        at android.bluetooth.BluetoothGatt.-wrap0(Unknown Source:0)
        at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:244)
        at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70)
        at android.os.Binder.execTransact(Binder.java:697)
     Caused by: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from 00:00:00:00:00:00
        at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback$2.onConnectionStateChange(RxBleGattCallback.java:77) 
        at android.bluetooth.BluetoothGatt$1$4.run(BluetoothGatt.java:249) 
        at android.bluetooth.BluetoothGatt.runOrQueueCallback(BluetoothGatt.java:725) 
        at android.bluetooth.BluetoothGatt.-wrap0(Unknown Source:0) 
        at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:244) 
        at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70) 
        at android.os.Binder.execTransact(Binder.java:697) 

@dariuszseweryn dariuszseweryn changed the title Crash when trying to connect too fast Crash when trying to connect too fast [UndeliverableException] Apr 9, 2018
@GuillaumeBourge
Copy link
Contributor Author

I don't know if it's linked, but i noticed this error in log (not app crash, it's correctly handled) during a connection lost (ble device turned off)

04-16 15:46:52.882 9815-9903/fr.my.app D/BluetoothGatt: close()
04-16 15:46:52.895 9815-9829/fr.my.app W/BluetoothGatt: Unhandled exception in callback
    java.lang.NullPointerException: Attempt to invoke interface method 'void io.reactivex.ObservableEmitter.onNext(java.lang.Object)' on a null object reference
        at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter.notifySubscribersAboutException(DisconnectionRouter.java:125)
        at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter.onExceptionOccurred(DisconnectionRouter.java:114)
        at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter.onDisconnectedException(DisconnectionRouter.java:100)
        at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback$2.onConnectionStateChange(RxBleGattCallback.java:77)
        at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:191)
        at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70)
        at android.os.Binder.execTransact(Binder.java:565)

I have no more crash with latest update for this moment on my side

@ghost
Copy link

ghost commented Apr 18, 2018

@guillaumebo which version are u using?

@GuillaumeBourge
Copy link
Contributor Author

The rx2 1.6 Snapshot

@szymonkozak
Copy link

I have the same problem, but in another place (ConnectionOperationQueueImpl.flushQueue)

05-16 16:45:45.496 27429-27742/com.mypackage E/AndroidRuntime: FATAL EXCEPTION: pool-4-thread-1
    Process: com.mypackage, PID: 27429
    io.reactivex.exceptions.UndeliverableException: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from stripped device address
        at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
        at io.reactivex.internal.operators.observable.ObservableFlatMapCompletableCompletable$FlatMapCompletableMainObserver.onError(ObservableFlatMapCompletableCompletable.java:130)
        at io.reactivex.internal.operators.observable.ObservableFlatMapCompletableCompletable$FlatMapCompletableMainObserver.innerError(ObservableFlatMapCompletableCompletable.java:165)
        at io.reactivex.internal.operators.observable.ObservableFlatMapCompletableCompletable$FlatMapCompletableMainObserver$InnerObserver.onError(ObservableFlatMapCompletableCompletable.java:183)
        at io.reactivex.internal.operators.completable.CompletableFromSingle$CompletableFromSingleObserver.onError(CompletableFromSingle.java:41)
        at io.reactivex.internal.operators.observable.ObservableElementAtSingle$ElementAtObserver.onError(ObservableElementAtSingle.java:104)
        at io.reactivex.internal.operators.observable.ObservableDelaySubscriptionOther$DelayObserver$OnComplete.onError(ObservableDelaySubscriptionOther.java:99)
        at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.tryOnError(ObservableCreate.java:85)
        at com.polidea.rxandroidble2.internal.serialization.ConnectionOperationQueueImpl.flushQueue(ConnectionOperationQueueImpl.java:92)
        at com.polidea.rxandroidble2.internal.serialization.ConnectionOperationQueueImpl.access$200(ConnectionOperationQueueImpl.java:34)
        at com.polidea.rxandroidble2.internal.serialization.ConnectionOperationQueueImpl$1.run(ConnectionOperationQueueImpl.java:83)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
        at java.lang.Thread.run(Thread.java:818)
     Caused by: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from stripped device address
        at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback$2.onConnectionStateChange(RxBleGattCallback.java:77)
        at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:181)
        at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70)
        at android.os.Binder.execTransact(Binder.java:453)

Version 1.6.0-SNAPSHOT (but bug appears also in 1.5.0-SNAPSHOT)

@thuytrinh
Copy link
Contributor

I confirmed that this still happened w/ 1.6.0-SNAPSHOT. In my cases, it happened when I disposed explicitly via subscriptions.dispose() or via switchMap().

05-16 15:04:42.322 32627-1379/bike.cobi.app.debug E/AndroidRuntime: FATAL EXCEPTION: RxCachedThreadScheduler-6
    Process: bike.cobi.app.debug, PID: 32627
    io.reactivex.exceptions.UndeliverableException: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from 7C:57:4E:00:12:85
        at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:314)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.operators.observable.ObservableReplay$ReplayObserver.dispose(ObservableReplay.java:276)
        at io.reactivex.disposables.CompositeDisposable.dispose(CompositeDisposable.java:217)
        at io.reactivex.disposables.CompositeDisposable.dispose(CompositeDisposable.java:80)
        at io.reactivex.internal.operators.observable.ObservableRefCount$DisposeTask.run(ObservableRefCount.java:219)
        at io.reactivex.disposables.RunnableDisposable.onDisposed(RunnableDisposable.java:30)
        at io.reactivex.disposables.RunnableDisposable.onDisposed(RunnableDisposable.java:20)
        at io.reactivex.disposables.ReferenceDisposable.dispose(ReferenceDisposable.java:43)
        at io.reactivex.internal.operators.observable.ObservableRefCount$ConnectionObserver.dispose(ObservableRefCount.java:151)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.disposables.SequentialDisposable.dispose(SequentialDisposable.java:73)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.dispose(ObservableFlatMap.java:594)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.disposeAll(ObservableFlatMap.java:520)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:311)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.disposeAll(ObservableFlatMap.java:514)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:311)
        at io.reactivex.internal.observers.BasicFuseableObserver.dispose(BasicFuseableObserver.java:152)
        at io.reactivex.internal.operators.observable.ObservableDoOnEach$DoOnEachObserver.dispose(ObservableDoOnEach.java:80)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.disposables.SequentialDisposable.dispose(SequentialDisposable.java:73)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.dispose(ObservableFlatMap.java:594)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.disposeAll(ObservableFlatMap.java:520)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:311)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.observers.LambdaObserver.dispose(LambdaObserver.java:100)
        at io.reactivex.disposables.CompositeDisposable.dispose(CompositeDisposable.java:217)
        at io.reactivex.disposables.CompositeDisposable.dispose(CompositeDisposable.java:80)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.operators.completable.CompletableCreate$Emitter.dispose(CompletableCreate.java:114)
        at io.reactivex.internal.operators.completable.CompletablePeek$CompletableObserverImplementation.dispose(CompletablePeek.java:138)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
        at io.reactivex.internal.operators.mixed.ObservableSwitchMapCompletable$SwitchMapCompletableObserver$SwitchMapInnerObserver.dispose(ObservableSwitchMapCompletable.java:233)
05-16 15:04:42.329 32627-1379/bike.cobi.app.debug E/AndroidRuntime:     at io.reactivex.internal.operators.mixed.ObservableSwitchMapCompletable$SwitchMapCompletableObserver.onNext(ObservableSwitchMapCompletable.java:116)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:200)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252)
        at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
        at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from 7C:57:4E:00:12:85
        at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter$3.apply(DisconnectionRouter.java:58)
        at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter$3.apply(DisconnectionRouter.java:55)
        at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:59)
        at io.reactivex.internal.operators.observable.ObservableFilter$FilterObserver.onNext(ObservableFilter.java:52)
        at io.reactivex.internal.operators.observable.ObservableConcatMap$ConcatMapDelayErrorObserver$DelayErrorInnerObserver.onNext(ObservableConcatMap.java:500)
        at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:64)
        at com.polidea.rxandroidble2.RxBleAdapterStateObservable$1.onReceive(RxBleAdapterStateObservable.java:62)
        at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0(LoadedApk.java:1331)
        at android.app.-$$Lambda$LoadedApk$ReceiverDispatcher$Args$_BumDX2UKsnxLVrE6UJsJZkotuA.run(Unknown Source:2)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6649)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826)

I temporarily set up an RxJava hook like below to workaround it:

class SetUpRxJavaErrorHandler() {
    operator fun invoke() = RxJavaPlugins.setErrorHandler({ error ->
        when {
            error is UndeliverableException && error.cause is BleDisconnectedException ->
                workaroundRxAndroidBleIssue(error)
            else -> throw error
        }
    })

    private fun workaroundRxAndroidBleIssue(error: Throwable) {
        Log.e(TAG, "Encountered https://github.com/Polidea/RxAndroidBle/issues/383", error)
    }
}

@dariuszseweryn
Copy link
Owner

Hello everyone,

I was investigating this issue recently.

The root cause of the problem is the threading of Android OS — callbacks may be called on arbitrary threads.
The library does not know how it will be used and thus it is routing errors to all listeners.
Because the errors sometimes may be routed through many merged observables they may appear more than once in an observable chain...

One of the differences between RxJava 1 and RxJava 2 is that the former did swallow exceptions that happened after the chain was unsubscribed whereas the latter is throwing an UndeliverableException in this situation.
With the current library architecture it is impossible to mitigate this behaviour and the suggested workaround is to add a code similar to what @thuytrinh wrote above:

Kotlin

RxJavaPlugins.setErrorHandler({ error ->
    if (error is UndeliverableException && error.cause is BleException) {
        return // ignore BleExceptions as they were surely delivered at least once
    }
    // add other custom handlers if needed
    throw error
})

Java

RxJavaPlugins.setErrorHandler(error -> {
    if (error instanceof UndeliverableException && error.cause instanceof BleException) {
        return; // ignore BleExceptions as they were surely delivered at least once
    }
    // add other custom handlers if needed
    throw error;
});

@jaesga
Copy link

jaesga commented May 23, 2018

@dariuszseweryn Where do you place that code for the workaround? Maybe inside your Applicatio class?

@dariuszseweryn
Copy link
Owner

Basically anywhere. RxJavaPlugins.setErrorHandler() is a static method.

@RobLewis
Copy link

RobLewis commented Jun 6, 2018

Don't really know what I'm talking about here, but this says that RxJavaPlugins have been deprecated in favor of RxJavaHooks. The relevant one would seem to be onError( Action1<Throwable> ). Might note this in the wiki.

@thuytrinh
Copy link
Contributor

That link seems to be relevant to RxJava 1.x only. The Java doc for RxJavaPlugins of RxJava 2.x has no depreciation on the class http://reactivex.io/RxJava/2.x/javadoc/io/reactivex/plugins/RxJavaPlugins.html.

@cuiti
Copy link

cuiti commented Jul 11, 2018

@DariuszAniszewski I can't seem to compile the workaround, since throw error causes an UnhandledException error. Any ideas?

@dariuszseweryn
Copy link
Owner

Hello @cuiti
I do not know exactly what is the issue you are facing. Maybe your project does not use Kotlin and/or Java lambdas?

@rzetzsche
Copy link

rzetzsche commented Jul 11, 2018

@cuiti Yes that is right. You get an unhandled exception when you try to rethrow the error in Java.

I'm using the folowing in my project:

RxJavaPlugins.setErrorHandler(error -> {
            if (error instanceof UndeliverableException && error.getCause() instanceof BleException) {
                return; // ignore BleExceptions as they were surely delivered at least once
            } else {
                throw new Exception(error);
            }
        });

@mohsenoid
Copy link

based on this doc
https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling

it would be nice if the library avoid the exceptions like this

// in some library
try {
   doSomethingBlockingly()
} catch (InterruptedException ex) {
   // check if the interrupt is due to cancellation
   // if so, no need to signal the InterruptedException
   if (!disposable.isDisposed()) {
      observer.onError(ex);
   }
}

@dariuszseweryn
Copy link
Owner

Thank you for the suggestion.
Unfortunately this is not the case in this library since the wrapped error is usually BleDisconnectedException. It happens due to the exception being routed to every Observable/Single/Completable derived from RxBleConnection.

If the user creates a single Observable from multiple others derived from RxBleConnection — the BleDisconnectedException will get emitted from all of them and only one will get handled by the Subscriber. The rest will get routed as UndeliverableExceptions — I have an idea on how to mitigate this problem but it will make the library harder to use — the user would need to think on where they want to get the error routed in their chain of Observables. And it could potentially drastically alter the API where if error is not routed to a particular place then e.g. a Maybe would be returned instead of Single.

This approach needs to get evaluated.

@Francis-Valcke
Copy link

Greetings

I am getting the same issues as described above in version 1.8.1.
So this "problem" will not get fixed?
Am i to understand that you deliberately leave this in for ease of use of the library?
I guess I can just handle this error globaly however I am not a fan of this method.
Other than this I am very content with the library by the way. Great job!

@dariuszseweryn
Copy link
Owner

So this "problem" will not get fixed?

No. At least not yet.

Am i to understand that you deliberately leave this in for ease of use of the library?

Partially. I do not have enough time to develop a new API that could allow for elimination the UndeliverableException issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug that is caused by the library help wanted
Projects
None yet
Development

No branches or pull requests