Dmytro Serdiuk
01/19/2024, 8:13 PM@OptIn(DelicateCoroutinesApi::class) fun main() = runBlocking { //sampleStart
val handler = CoroutineExceptionHandler { _, exception ->
println("CoroutineExceptionHandler got $exception")
}
val job = GlobalScope.launch(handler) {
val inner = launch { // all this stack of coroutines will get cancelled #3
launch {
launch {
throw IOException() // the original exception #1
}
}
}
try {
inner.join()
} catch (e: CancellationException) {
println("Rethrowing CancellationException with original cause")
throw e // cancellation exception is rethrown, yet the original IOException gets to the handler #6
}
}
job.join()
}
If I understand correctly, top-level launch was already cancelled by throw IOException, so what is the purpose of the next code?How it would be treated?
try {
inner.join()
} catch (e: CancellationException) {
println("Rethrowing CancellationException with original cause")
throw e // cancellation exception is rethrown, yet the original IOException gets to the handler #6
}
I also saw in the documentation “Cancellation exceptions are transparent and are unwrapped by default”, but I don’t understand how it relates to this code at all.
Thank you very much for your helpChris Lee
01/19/2024, 8:25 PMDmytro Serdiuk
01/19/2024, 8:27 PMChris Lee
01/19/2024, 8:31 PMDmytro Serdiuk
01/19/2024, 8:37 PMDmytro Serdiuk
01/19/2024, 8:40 PMChris Lee
01/19/2024, 8:41 PMDmytro Serdiuk
01/19/2024, 8:43 PMNormally, uncaught exceptions can only result from root coroutines created using the launch builder. All children coroutines (coroutines created in the context of another Job) delegate handling of their exceptions to their parent coroutine, which also delegates to the parent, and so on until the root, so the CoroutineExceptionHandler installed in their context is never used.
https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-exception-handler/Dmytro Serdiuk
01/20/2024, 10:41 AMSam
01/20/2024, 12:53 PMSam
01/20/2024, 12:53 PMthrow IOException()
propagates up through all three calls to launch
, causing job
to fail. In this case we can think of "failure" as a specific type of cancellation.Sam
01/20/2024, 12:54 PMDmytro Serdiuk
01/20/2024, 12:55 PMDmytro Serdiuk
01/20/2024, 12:55 PMDmytro Serdiuk
01/20/2024, 12:55 PMSam
01/20/2024, 12:56 PMSam
01/20/2024, 12:57 PMSam
01/20/2024, 12:58 PMjoin()
) in a coroutine that has already failed. The cause
of the cancellation exception is unimportant. If it gets rethrown, it will simply be ignored, because the job has already failed with a different exception.Dmytro Serdiuk
01/20/2024, 12:59 PMDmytro Serdiuk
01/20/2024, 12:59 PMDmytro Serdiuk
01/20/2024, 12:59 PMDmytro Serdiuk
01/20/2024, 1:00 PMSam
01/20/2024, 1:00 PMSam
01/20/2024, 1:02 PMDmytro Serdiuk
01/20/2024, 1:03 PM