Taras Parshenko
Taras Parshenko

Reputation: 604

How to ignore JobCancellationException?

Recently, I've upgraded Kotlin Coroutines from experimental to 1.1.1 and faced the problem that job.cancel() in new version works differently.

Here's the code with Experimental Coroutines:

fun <R : Any, T : Deferred<R>> T.runAsync(
        job: Job,
        onSuccess: (result: R) -> Unit,
        onFailed: (errorMsg: String?) -> Unit) {
    launch(UI, parent = job) {
        try {
            val result = [email protected]()
            onSuccess(result)
        } catch (e: Exception) {
            onFailed(e.message)
        }
    }
}

Here's with 1.1.1:

fun <R : Any, T : Deferred<R>> T.runAsync(
        job: Job,
        onSuccess: (result: R) -> Unit,
        onFailed: (errorMsg: String?) -> Unit) {
    GlobalScope.launch(Dispatchers.Main + job) {
        try {
            val result = withContext(Dispatchers.IO) {
                [email protected]()
            }
            onSuccess(result)
        } catch (e: Exception) {
            onFailed(e.message)
        }
    }
}

For example:

My fragment destroyed and called job.cancel() during coroutine is running.

In experimental coroutines neither onSuccess() nor onFailed() will be called.

In 1.1.1: onFailed() called because caught of JobCancellationException

I figured out to add catch (e: JobCancellationException), but it's impossible:

/**
 * @suppress **This an internal API and should not be used from general code.**
 */
internal expect class JobCancellationException(

So, the question is: How to handle/ignore JobCancellationException ?

Upvotes: 13

Views: 11108

Answers (1)

Kiskae
Kiskae

Reputation: 25583

You try to catch the super-class CancellationException instead, which is a part of the public API.

Do note that if something throws CancellationException you are generally expected to rethrow it so upstream objects are notified about the cancellation. See Cancellation is Cooperative

Upvotes: 25

Related Questions