CancellationException signals that a Kotlin coroutine has been cancelled. Coroutines usually throw it at suspension points, allowing cancellation to propagate through the coroutine hierarchy. section 15.2.4
Do not swallow cancellation
A broad catch can accidentally defeat cancellation: try { doWork() } catch (e: Exception) { println("Oops: ${e.message}") } Because CancellationException is an Exception, this loop may continue after withTimeoutOrNull requests cancellation. Catch only the expected failure, or rethrow CancellationException before handling other exceptions. section 15.2.4
Use cancellation cooperatively when work does not regularly suspend:
- Check isActive after a unit of CPU-heavy work and return when the scope is no longer active. section 15.2.6
- Call ensureActive() to perform the check and throw CancellationException when cancellation has occurred. section 15.2.6
- Let Flow's catch operator handle ordinary upstream failures without treating cancellation as a recoverable error; it is not invoked for cancellation. section 18.4.1
val myJob = launch {
repeat(5) {
doCpuHeavyWork()
ensureActive()
}
}
A compact pattern for making repeated CPU-heavy work cancellable with ensureActive(). section 15.2.6
