'Where should I catch the InterruptedException thrown by FirestorePagingAdapter - FirebaseUI-Android
A handful of my users are experiencing a crash according to Firebase Crashlytics:
Fatal Exception: io.reactivex.rxjava3.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | java.lang.InterruptedException
at io.reactivex.rxjava3.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:2)
at io.reactivex.rxjava3.internal.operators.single.SingleFromCallable.subscribeActual(SingleFromCallable.java:54)
at io.reactivex.rxjava3.core.Single.subscribe(Single.java:8)
at io.reactivex.rxjava3.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.run(SingleSubscribeOn.java:2)
at io.reactivex.rxjava3.core.Scheduler$DisposeTask.run(Scheduler.java:9)
at io.reactivex.rxjava3.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:13)
at io.reactivex.rxjava3.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java)
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:923)
Caused by java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1024)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1334)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:232)
at com.google.android.gms.tasks.zzaa.zza(zzaa.java:2)
at com.google.android.gms.tasks.Tasks.await(Tasks.java:28)
at com.firebase.ui.firestore.paging.FirestorePagingSource.lambda$loadSingle$0(FirestorePagingSource.java)
at com.firebase.ui.firestore.paging.FirestorePagingSource.$r8$lambda$aRsAFsiduxRWbX-Rs8tsd39JsV0(FirestorePagingSource.java)
at com.firebase.ui.firestore.paging.FirestorePagingSource$$InternalSyntheticLambda$0$301762c7c2c4bb9cc6676b1600ffb92473af44448cde26854aae0b3e15f6f4f6$0.call$bridge(FirestorePagingSource.java:92)
at io.reactivex.rxjava3.internal.operators.single.SingleFromCallable.subscribeActual(SingleFromCallable.java:16)
at io.reactivex.rxjava3.core.Single.subscribe(Single.java:8)
at io.reactivex.rxjava3.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.run(SingleSubscribeOn.java:2)
at io.reactivex.rxjava3.core.Scheduler$DisposeTask.run(Scheduler.java:9)
at io.reactivex.rxjava3.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:13)
at io.reactivex.rxjava3.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java)
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:923)
I have trouble reproducing the error on my end. However, in the Further reading linked in the error message I can read the following, which seems to be relatable to my problem:
In addition, some 3rd party libraries/code throw when they get interrupted by a cancel/dispose call which leads to an undeliverable exception most of the time. Internal changes in 2.0.6 now consistently cancel or dispose a Subscription/Disposable before cancelling/disposing a task or worker (which causes the interrupt on the target thread).
// in some 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); } }If the library/code already did this, the undeliverable InterruptedExceptions should stop now. If this pattern was not employed before, we encourage updating the code/library in question.
Below is the code where I set up the FirestorePagingAdapter, using FirebaseUI-Android. As stated it works perfect for all but a handful of users.
com.google.firebase.firestore.Query feedBaseQuery = firebaseHelper.getFeedBaseQuery();
PagingConfig config = new PagingConfig(10, 5, false);
FirestorePagingOptions<FeedObject> options = new FirestorePagingOptions.Builder<FeedObject>()
.setLifecycleOwner(mainActivity)
.setQuery(feedBaseQuery, config, FeedObject.class)
.build();
this.feedAdapter = new FirestoreFeedAdapter(mainActivity, options);
recyclerView.setHasFixedSize(false);
recyclerView.setLayoutManager(new LinearLayoutManager(mainActivity));
recyclerView.setAdapter(this.feedAdapter);
So, my best guess right now is that the app gets interrupted somehow when retrieving data from Firestore which trows an InterruptedException which is never caught. I guess my question is if and where I should catch the InterruptedException?
Solution 1:[1]
I had same error when I change fragment quickly with really bad network or in offline mode, not really nice but I added that on my application class. And it worked fine...
RxJavaPlugins.setErrorHandler { e ->
if (e is UndeliverableException) {
Log.d(TAG, e.toString())
} else {
Thread.currentThread().also { thread ->
thread.uncaughtExceptionHandler.uncaughtException(thread, e)
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | gizmoog |
