basic-log-and-rethrow
In this example we have 2 co-routines:
- First co-routine is going to throw exception after 2 seconds.
- Second co-routine is processing some unrelated messages every half second.
Once 1st co-routine throws exception:
- Second co-routine gets Cancellation Exception on invocation of
delay()
(delay is Cancellation Cooperative Functions/suspension point) - The exception is rethrown to the parent and the catch block within main() catches the exception.
Code
package com.glassthought.sandbox
import gt.sandbox.util.output.Out
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
suspend fun main(): kotlin.Unit {
val out = Out.standard()
out.info("START")
try {
val runBlocking = runBlocking {
launch(CoroutineName("WillFail")) {
val timeMillis = 2000L
out.info("This one will throw in $timeMillis ms")
delay(timeMillis)
out.warn("OK I am about to throw an exception!")
throw MyExceptionWillThrowFromCoroutine("I-Failed-In-CoRoutine")
}
launch(CoroutineName("JustPrints")) {
(0..10)
.map { "a-${it}" }
.forEach {
out.info(it)
try {
delay(500)
} catch (e: CancellationException) {
val excMsg = e.message ?: e.toString()
out.warn("I have caught [${e::class.simpleName}/$excMsg], and rethrowing it")
throw e
}
}
}
}
} catch (e: Exception) {
out.error("runBlocking threw an exception! of type=[${e::class.simpleName}] with msg=[${e.message}]")
}
out.info("DONE")
}
class MyExceptionWillThrowFromCoroutine(msg: String) : RuntimeException(msg)
Command to reproduce:
gt.sandbox.checkout.commit fc980e0c3d78ab332670 \
&& cd "${GT_SANDBOX_REPO}" \
&& cmd.run.announce "./gradlew run --quiet"
Recorded output of command:
Picked up JAVA_TOOL_OPTIONS: -Dkotlinx.coroutines.debug
Picked up JAVA_TOOL_OPTIONS: -Dkotlinx.coroutines.debug
[INFO][elapsed: 17ms][🥇][🧵][tname:main/tid:1] START
[INFO][elapsed: 49ms][🥇][1️⃣][coroutname:@WillFail#2][tname:main/tid:1] This one will throw in 2000 ms
[INFO][elapsed: 57ms][🥇][2️⃣][coroutname:@JustPrints#3][tname:main/tid:1] a-0
[INFO][elapsed: 558ms][🥇][2️⃣][coroutname:@JustPrints#3][tname:main/tid:1] a-1
[INFO][elapsed: 1058ms][🥇][2️⃣][coroutname:@JustPrints#3][tname:main/tid:1] a-2
[INFO][elapsed: 1558ms][🥇][2️⃣][coroutname:@JustPrints#3][tname:main/tid:1] a-3
[WARN][elapsed: 2054ms][🥇][1️⃣][coroutname:@WillFail#2][tname:main/tid:1] OK I am about to throw an exception!
[WARN][elapsed: 2103ms][🥇][2️⃣][coroutname:@JustPrints#3][tname:main/tid:1] I have caught [JobCancellationException/Parent job is Cancelling], and rethrowing it
[ERROR][elapsed: 2104ms][🥇][🧵][tname:main/tid:1] runBlocking threw an exception! of type=[MyExceptionWillThrowFromCoroutine] with msg=[I-Failed-In-CoRoutine]
[INFO][elapsed: 2104ms][🥇][🧵][tname:main/tid:1] DONE
Backlinks