Kas notiek ar korutīnu, kad rodas izņēmums?
sobes.tech AI
Atbilde no AI
Kad korutīnā rodas izņēmums, tā apstrādes veids ir atkarīgs no izņēmuma veida (un dispatcher/konteksta iestatījumiem).
-
Nekontrolēts izņēmums: Ja izņēmums nav noķerts korutīnā, tas tiek propagēts augšup pa korutīnu hierarhiju līdz tuvākajam
Job(vaiCoroutineScope). Uzvedība ir atkarīga noJobveida:Job: Pēc noklusējuma, ja notiek izņēmums bērnu korutīnā, vecākaJobtiek atcelta, kas noved pie visu citu tās bērnu korutīnu atcelšanas. Izņēmums tiek pārsūtīts augšup.SupervisorJob:SupervisorJobnetiek atcelts, ja notiek izņēmums bērnu korutīnā. Tikai tā korutīna, kurā notika izņēmums, tiks atcelta. Tas ir noderīgi, ja nepieciešams, lai viena bērna uzdevuma atcelšana neietekmētu citas.CoroutineScopegalvenais: Ja izņēmums sasniedzCoroutineScope(piemēram,GlobalScopevaiCoroutineScopeizveidots bezJob), tas tiek nodots globālajam izņēmumu apstrādātājamCoroutineExceptionHandler. Pēc noklusējuma, ja nav reģistrēts apstrādātājs, izņēmums tiek reģistrētsSystem.err.
-
Noķerts izņēmums: Ja izņēmums tiek noķerts ar
try-catchbloku korutīnā, tas tiek apstrādāts lokāli, un korutīna turpina darbu pēccatchbloka, ja tas ir iespējams. Izņēmums netiek pārsūtīts augšup. -
Saistītie ar atcelšanu izņēmumi (piemēram,
CancellationException): Šie izņēmumi ir īpaši. Tie tiek izmantoti korutīnu atcelšanas mehānisma nodrošināšanai un parasti tiek ignorēti lielākajā daļā izņēmumu apstrādātāju pēc noklusējuma. Tie nerada fatālu kļūmi vecāJobgadījumā. -
async-a izņēmumi: Korutīna, kas sākta arasync, ievieto izņēmumu savāDeferred. Izņēmums tiek pārsūtīts tikai, izsaucot.await()uz šīDeferred. Līdz tam izņēmums ir "slēpts".
import kotlinx.coroutines.*
fun main() = runBlocking {
val scope = CoroutineScope(SupervisorJob())
scope.launch {
try {
println("Korutīna 1 sākās")
delay(100)
throw RuntimeException("Kas notika Korutīnā 1")
} catch (e: Exception) {
println("Noķerts izņēmums Korutīnā 1: ${e.message}")
}
}
scope.launch {
println("Korutīna 2 sākās")
delay(500)
println("Korutīna 2 pabeigta")
}
delay(1000) // Gaidām rezultātu
scope.cancel() // Atceļam scope
}
Šajā piemērā, izņēmums Korutīnā 1 ir noķerts, un Korutīna 2 turpina darbu, jo ir izmantots SupervisorJob. Ja būtu izmantots parasts Job, tad izņēmums Korutīnā 1 izraisītu Korutinas 2 atcelšanu.