Open
Description
Describe the bug
During the review of #4181, it became evident that we don't properly handle failures in coroutine dispatchers, and this can surface in ways other than just strange-looking exceptions.
Provide a Reproducer
val dispatcher = newSingleThreadContext("unreliable friend")
runTest {
launch(dispatcher, start = CoroutineStart.UNDISPATCHED) {
try {
println("This code runs...")
suspendCancellableCoroutine<Int> { cont ->
// we launch a separate thread and wait a bit,
// because we want the coroutine to actually suspend
// and go through a dispatch.
launch(Dispatchers.Default) {
delay(100)
// close the dispatcher, now it will throw on `dispatch`
dispatcher.close()
// try dispatching the coroutine
cont.resume(3)
}
}
} catch (e: Throwable) {
println("Caught $e")
throw e
} finally {
println("... therefore, this code must run.")
}
}
}
This code will hang after printing This code runs...
, as the launched coroutine never finishes.