Wat gebeurt er met een coroutine wanneer er een uitzondering optreedt?
sobes.tech AI
Antwoord van AI
Wanneer er een uitzondering optreedt binnen een coroutine, bepaalt de afhankelijkheid van het type uitzondering (en de dispatcher/context-instellingen) hoe deze wordt afgehandeld.
-
Ongecontroleerde uitzondering: Als de uitzondering niet binnen de coroutine wordt opgevangen, wordt deze omhoog in de hiërarchie van coroutines doorgegeven tot aan de dichtstbijzijnde
JobofCoroutineScope. Het gedrag hangt af van het typeJob:Job: Standaard wordt, wanneer een uitzondering optreedt in een kind-coroutine, de bovenliggendeJobgeannuleerd, wat leidt tot het annuleren van alle andere onderliggende coroutines. De uitzondering wordt omhoog doorgegeven.SupervisorJob: De bovenliggendeSupervisorJobwordt niet geannuleerd wanneer een uitzondering optreedt in een kind-coroutine. Alleen de coroutine waarin de uitzondering plaatsvond, wordt geannuleerd. Dit is handig wanneer je wilt dat het annuleren van een kind-taak de anderen niet beïnvloedt.CoroutineScoperoot: Als de uitzondering deCoroutineScoperoot bereikt (bijvoorbeeldGlobalScopeof een scope gemaakt metCoroutineScopezonderJob), wordt deze doorgestuurd naar de globaleCoroutineExceptionHandler. Standaard wordt, als er geen handler is geregistreerd, de uitzondering gelogd inSystem.err.
-
Opgevangen uitzondering: Als de uitzondering wordt opgevangen met een
try-catch-blok binnen de coroutine, wordt deze lokaal afgehandeld en gaat de coroutine verder na hetcatch-blok, indien mogelijk. De uitzondering wordt niet omhoog doorgegeven. -
Uitzonderingen gerelateerd aan annulering (bijvoorbeeld
CancellationException): Deze uitzonderingen zijn speciaal. Ze worden gebruikt voor het annuleringmechanisme van coroutines en worden meestal genegeerd door de meeste standaard exception handlers. Ze veroorzaken niet standaard een fatale fout in de bovenliggendeJob. -
Uitzonderingen in
async: Een metasyncgestartde coroutine plaatst de uitzondering in haarDeferred. De uitzondering wordt alleen doorgegeven bij het aanroepen van.await()op datDeferred. Tot die tijd is de uitzondering "verborgen".
import kotlinx.coroutines.*
fun main() = runBlocking {
val scope = CoroutineScope(SupervisorJob())
scope.launch {
try {
println("Coroutine 1 gestart")
delay(100)
throw RuntimeException("Er is iets misgegaan in Coroutine 1")
} catch (e: Exception) {
println("Opgevangen uitzondering in Coroutine 1: ${e.message}")
}
}
scope.launch {
println("Coroutine 2 gestart")
delay(500)
println("Coroutine 2 voltooid")
}
delay(1000) // Wacht om de output te zien
scope.cancel() // Annuleer scope
}
In dit voorbeeld wordt de uitzondering in Coroutine 1 opgevangen en gaat Coroutine 2 door met uitvoeren omdat SupervisorJob wordt gebruikt. Als in plaats daarvan een gewone Job zou worden gebruikt, zou de uitzondering in Coroutine 1 leiden tot het annuleren van Coroutine 2.