Zach Klippenstein (he/him) [MOD]
09/15/2018, 5:28 PMJob
from a runBlocking
scope. Changing the dispatcher doesn’t seem to matter, and coroutines `launch`ed from GlobalScope
execute the handler as I’d expect. I can’t see any documentation about this or figure out how this makes sense.
E.g.
fun main(args: Array<String>) {
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught $exception")
}
runBlocking(handler) {
val job = launch {
// This exception is thrown from runBlocking, and not seen by handler.
throw AssertionError()
}
job.join()
}
}
If you change that to the following, handler
gets run:
runBlocking {
val job = GlobalScope.launch(handler) {
Is this behavior by design?Zach Klippenstein (he/him) [MOD]
09/15/2018, 10:43 PMrunBlocking
parent job implies there is a well-defined place in the code where the exception can be caught, unlike a GlobalScope.launch
.Dico
09/16/2018, 2:50 AMDico
09/16/2018, 2:51 AMelizarov
09/16/2018, 8:08 PMelizarov
09/16/2018, 8:09 PMCoroutineExceptionHandler
is a handler for uncaught exceptions, while child coroutines effectively have their exceptions “caught” by their parentelizarov
09/16/2018, 8:11 PMGlobalScope.launch
completely decouples coroutine from its parent. If you want to inherit parent’s dispatcher, but make it separate in terms of cancellation and exception you can do launch(NonCancellable)
Dico
09/16/2018, 8:28 PMZach Klippenstein (he/him) [MOD]
09/16/2018, 8:47 PMspand
09/17/2018, 5:47 AMCoroutineUncaughtExceptionHandler
then ?elizarov
09/17/2018, 6:05 AM