Recently I've been learning coroutines in detail, as I understand SupervisorJob()
gives us opportunity to not cancel all children if one of the children of coroutine is cancelled due to some reason.
It is said that coroutines started with coroutineScope
will cancel all children if one fails, but the ones started with supervisorScope
will only cancel the child which is failed
I wonder if I could change behaviour of CoroutineScope
by adding SupervisorJob
as CoroutineContext to it, but I couldn't get expected behaviour which is the thing I don't get
Expected behaviour - getData1() and getData3() result gets printed*
Actual: - getData2() cancels all coroutine
fun main() = runBlocking {
val exceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
println(throwable)
}
val customScope = CoroutineScope(SupervisorJob() + exceptionHandler)
customScope.launch {
launch {
getData1().also { println(it) }
}
launch {
getData2().also { println(it) }
}
launch {
getData3().also { println(it) }
}
}.join()
}
private suspend fun getData1(): String? {
delay(1000)
return "data 1"
}
private suspend fun getData2(): String? {
delay(300)
throw RuntimeException("While getting Data 2 exception happened")
}
private suspend fun getData3(): String? {
delay(800)
return "data 3"
}
You are not launching the three inner coroutines in
customScope
. You're launching them in the scope of the launched outer coroutine (by using implicitthis
to launch them). If you launch them from that custom scope that has a SupervisorJob, then it should work: