streetsofboston
04/29/2019, 4:05 PMval xHandlerParent = CoroutineExceptionHandler { c, e ->
println("Parent Handled Crash")
}
val xHandlerLeaf = CoroutineExceptionHandler { c, e ->
println("Leaf Handled Crash")
}
fun main() {
CoroutineScope(xHandlerParent).launch(xHandlerLeaf) {
delay(1000)
throw Exception("Some Exception 1")
}
Thread.sleep(2000)
}
prints out Leaf Handled Crash
.
However, I expected the output to be Parent Handled Crash
, because an exception bubbles up to the top-most parent and CoroutineExceptionHandler
of that top-most parent should be used.
If I replace CoroutineScope(xHandlerParent). ...
with runBlocking { ... }
, the xHandlerLeaf
is not used, as I expected, because the top-most parent is used and that is a scoped-parent that just throws the exception up the call-stack.
I’m not sure if this is a bug or if I don’t understand how exceptions are handled 🙂yousefa2
04/29/2019, 4:07 PMxHandlerLeaf
handles the exception which stops it from propagating to it's parent. That's why you don't get it in the parent.streetsofboston
04/29/2019, 4:08 PMfun main() {
runBlocking{
launch(xHandlerLeaf) {
delay(1000)
throw Exception("Some Exception 1")
}
}
Thread.sleep(2000)
}
the xHandlerLeaf
is not used.CoroutineExceptionHandler
of that parent is used.xHandlerParent
does handle the exception, as I expect:
fun main() {
CoroutineScope(Dispatchers.Default).launch(xHandlerParent) {
launch(xHandlerLeaf) {
delay(1000)
throw Exception("Some Exception 1")
}
}
Thread.sleep(2000)
}
Martín Ickowicz
04/29/2019, 7:25 PMCoroutineExceptionHandler
consumes the exception and does not propagates it
in your last example you are throwing a new exception, which is caught by the parent scopestreetsofboston
04/29/2019, 7:32 PMMartín Ickowicz
04/29/2019, 7:37 PM