Reputation: 604
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
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