Careeroza
coroutineScope vs supervisorScope
coroutineScope
coroutineScope { } creates a child scope inside a suspend function. It waits for all children, and if any child fails, all the others are cancelled and the exception is thrown to the caller.
Example
Payment fails, so the "send invoice" child is cancelled too.
import kotlinx.coroutines.*
suspend fun placeOrder(): Unit = coroutineScope {
launch {
try {
delay(500)
println("Invoice sent")
} catch (e: CancellationException) {
println("Invoice cancelled")
throw e
}
}
launch {
delay(100)
throw IllegalStateException("Payment declined")
}
}
fun main() = runBlocking {
try {
placeOrder()
} catch (e: IllegalStateException) {
println("Order failed: ${e.message}")
}
}Output
Invoice cancelled Order failed: Payment declined
supervisorScope
supervisorScope { } is the same, except a failing child does not cancel its siblings. Each child must handle its own error (try/catch or a CoroutineExceptionHandler).
Example
One widget fails, the other still loads.
import kotlinx.coroutines.*
fun main() = runBlocking {
val handler = CoroutineExceptionHandler { _, e -> println("Handled: ${e.message}") }
supervisorScope {
launch(handler) {
delay(100)
throw RuntimeException("Weather widget failed")
}
launch {
delay(300)
println("News widget loaded")
}
}
println("Screen ready")
}Output
Handled: Weather widget failed News widget loaded Screen ready
Which One?
| coroutineScope | supervisorScope | |
|---|---|---|
| Child fails | cancels siblings, rethrows | siblings keep running |
| Use when | all results are needed (all or nothing) | tasks are independent |
| Example | checkout: payment + stock reservation | dashboard widgets, uploading several photos |
Exercise: Upload three photos concurrently inside supervisorScope. Photo 2 throws an exception. Make sure photos 1 and 3 still print "uploaded" and the failure is printed by a handler.
Show answer
import kotlinx.coroutines.*
fun main() = runBlocking {
val handler = CoroutineExceptionHandler { _, e -> println("Failed: ${e.message}") }
supervisorScope {
for (i in 1..3) {
launch(handler) {
delay(i * 100L)
if (i == 2) throw RuntimeException("photo 2 too large")
println("Photo $i uploaded")
}
}
}
}