Don Mitchell
05/02/2025, 5:25 PMCoroutineScope.cancel
doesn't seem to work at least in the kotlin playground or I'm missing something. I expected the following to cancel on i==6
but it doesn't. It throws the error after the loop finishes.
import kotlinx.coroutines.*
@OptIn(DelicateCoroutinesApi::class)
suspend fun main() = coroutineScope {
repeat(10) { i ->
keepRunningUnlessFatal {
if (i == 3) {
println("throwing ISE")
throw IllegalStateException("Illegal 3")
}
if (i == 6) {
println("throwing OOM")
throw OutOfMemoryError("OOM")
}
println("i ${i}")
}
}
}
suspend fun <T> CoroutineScope.keepRunningUnlessFatal(
message: String = "Continuing execution after exception",
block: suspend () -> T
): T? = try {
block()
} catch (e: VirtualMachineError) {
this.cancel("FATAL_ERROR_MSG", e)
null
// HERE - uncomment to see difference
//throw e
} catch (e: InterruptedException) {
this.cancel("FATAL_ERROR_MSG", e)
null
} catch (e: LinkageError) {
this.cancel("FATAL_ERROR_MSG", e)
null
} catch (e: CancellationException) {
this.cancel(e)
null
} catch (e: Exception) {
println(e)
println(message)
null
}
ephemient
05/02/2025, 5:32 PMrepeat
or keepRunningUnlessFatal
checks if the scope is aliveephemient
05/02/2025, 5:36 PMsuspendCoroutine
or things built on similar primitives, as most suspending functions are), or if you explicitly called ensureActive()
Don Mitchell
05/02/2025, 5:38 PMensureActive()
and delay(i.milliseconds)
and it behaved as expected. good to knowDon Mitchell
05/02/2025, 5:40 PMthrow e
after the call to cancel
?trevjones
05/02/2025, 5:55 PM.onFailure { currentCoroutineContext().ensureActive() }
Don Mitchell
05/02/2025, 6:23 PMtrevjones
05/02/2025, 6:38 PMtrevjones
05/02/2025, 6:39 PMCLOVIS
05/05/2025, 9:45 AM