IllegalStateException : Already resumed

See original GitHub issue

Hi,

I am observing live data using observeForever() and then removing the observer later. I handle success and failure scenarios and resume the continuation object accordingly.

//failure removeObserver(observer) if (coroutine.isActive) coroutine.resume(getErrorState()) //success removeObserver(observer) if (coroutine.isActive) coroutine.resume(data)

In most cases it works fine. However, randomly few times I get exception :

Fatal Exception: java.lang.IllegalStateException: Already resumed, but proposed with update android.widget.RemoteViews@ebbd63d at kotlinx.coroutines.CancellableContinuationImpl.alreadyResumedError(CancellableContinuationImpl.java:277) at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.java:272) at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.java:189)

It seems , the isActive check isn’t behaving as expected. Please suggest a better check to avoid this crash.

Cheers !

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:18 (6 by maintainers)

github_iconTop GitHub Comments

4reactions
migmacdevcommented, Oct 6, 2021

Here are my 2 cents, I had the same issue when I wrapped an API callback into a suspendCancellableCoroutine, the callback inside was receiving calls in different methods, therefore cont.resume was being called twice, what I ended up doing was an extension function to only call resume if the cont was active, like:

private fun <T> CancellableContinuation<T>.resumeIfActive(value: T) {
    if(isActive) {
        resume(value)
    }
}

for my case, this works since I only care about the first call to cont.resume

1reaction
psteigercommented, Sep 10, 2021

@aruke a strategy I used to use was to save the continuation in a nullable var, resuming from the var and immediately setting it to null afterwards. Then, if other callbacks eventually try to resume it again, field will be null.

But honestly, it works but it’s flaky design. In my opinion you should only suspend and resume if there’s a single callback that is guaranteed to always run and run exactly once. For example, GMS tasks and addOnCompleteListener.

If you have a code snippet to share I could give further input.

Read more comments on GitHub >

github_iconTop Results From Across the Web

android - kotlin coroutine throws java.lang.IllegalStateException
According to documentation, it's possible to resume Continuation only single time. Second resume will throw IllegalStateException with ...
Read more >
Tests before commit: IllegalStateException: Already resumed
Sample project https://github.com/vbozh/pre-commit-checks-gradle. Try to commit file with running test configuration that fails
Read more >
suspendCancellableCoroutine - Kotlin
The suspended coroutine is resumed with the call it to its Continuation.resumeWith member function or to resume extension function.
Read more >
[Solved]-Kotlin withTimeout coroutine cancellation-kotlin
IllegalStateException : Already resumed, but got value Location · Kotlin Coroutine Testing with Dispatchers.IO · Kotlin Coroutine Unit Testing Error: ...
Read more >
CancellableContinuation - kotlinx-coroutines-core
Invocation of resume or resumeWithException in resumed state produces IllegalStateException but is ignored in cancelled state.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

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

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found