I am using the following snippet (in RxJava2) for retrieving a list of URL (from the network), and use each URL for downloading a file.
The imageService.download()
will run with a max concurrency value of 3.
disposable.add(imageRepository.getUrls()
.flatMap(url -> imageService.download(url)
.subscribeOn(schedulerProvider.io()), MAX_CONCURRENT_DOWNLOADS)
.flatMap(response -> fileManagerService.saveFile(response))
.subscribeOn(schedulerProvider.io())
.observeOn(schedulerProvider.ui())
.subscribe(file -> {}, throwable -> {}, () -> {}));
Everything works fine 99% of the time. But in some specific condition I get an UndeliverableException
: In particular when the Network connection is not available anymore, disposable.clear()
is called (this is automatically handled by a JobScheduler
component).
So what is actually happening is that I am trying to dispose the disposable and at the same time the imageService.download()
Observable will try to call onError
(HTTP error).
It seems like the disposing action doesn't "stop" the subscription in the inner flatMap
.
W/System.err: io.reactivex.exceptions.UndeliverableException: com.apollographql.apollo.exception.ApolloNetworkException: Failed to execute http call
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
09-19 11:37:59.501 23732-23732/app.dev W/System.err: at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:314)
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.disposables.DisposableHelper.dispose(DisposableHelper.java:125)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.dispose(ObservableSubscribeOn.java:73)
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.observers.LambdaObserver.dispose(LambdaObserver.java:102)
at io.reactivex.disposables.CompositeDisposable.dispose(CompositeDisposable.java:235)
at io.reactivex.disposables.CompositeDisposable.clear(CompositeDisposable.java:201)
Should I handle the error at a global level? with ( RxJavaPlugins.setErrorHandler
) or there is a better way for preventing it to happen?