Sobes.tech
Middle

Mida juhtub korutinaiga, kui tekib erand?

sobes.tech AI

Vastus AI-lt

Kui korutinas tekib erand, sõltub selle erandi tüübist (ja dispacheri/konteksti seadistustest), kuidas seda töödeldakse.

  • Mittekontrollitud erand: Kui erand ei ole korutinas kinni püütud, levib see korutinate hierarhias ülespoole kuni lähima Job (või CoroutineScope). Käitumine sõltub Job tüübist:

    • Job: Vaikimisi, kui tekib erand lapse korutinas, tühistatakse vanem Job, mis viib kõigi selle teise lapse korutinate tühistamiseni. Erand edastatakse ülespoole.
    • SupervisorJob: SupervisorJob ei tühistata erandi korral lapse korutinas. Tühistatakse ainult see korutina, kus erand tekkis. Kasulik olukord, kus ühe lapse tühistamine ei tohiks mõjutada teisi.
    • CoroutineScope põhine: Kui erand jõuab CoroutineScope-i (näiteks GlobalScope või CoroutineScope ilma Job-ita), edastatakse see globaalsetele erandite töötlejatele CoroutineExceptionHandler. Vaikimisi logitakse erand System.err-i.
  • Kinni püütud erand: Kui erand on korutinas try-catch-iga kinni püütud, töödeldakse seda lokaalselt ja korutina jätkab pärast catch-i, kui see on võimalik. Erandit ei edastata ülespoole.

  • Seotud erandid tühistamisega (näiteks CancellationException): Need erandid on eriliselt. Kasutatakse korutinate tühistamise mehhanismi ja neid ignoreeritakse enamikus erandite töötlejates vaikimisi. Need ei põhjusta fataalset riket vanem Job-is.

  • async-i erandid: async-iga käivitatud korutina paneb erandi oma Deferred-i. Erand edastatakse ainult .await()-i kutsumisel sellel Deferred-il. Enne seda on erand "peidetud".

import kotlinx.coroutines.*

fun main() = runBlocking {
    val scope = CoroutineScope(SupervisorJob())

    scope.launch {
        try {
            println("Korutina 1 algas")
            delay(100)
            throw RuntimeException("Midagi läks valesti Korutinas 1")
        } catch (e: Exception) {
            println("Kinni püütud erand Korutinas 1: ${e.message}")
        }
    }

    scope.launch {
        println("Korutina 2 algas")
        delay(500)
        println("Korutina 2 lõpetas")
    }

    delay(1000) // Ootame tulemusi
    scope.cancel() // Tühistame scope
}

Selles näites on erand Korutinas 1 kinni püütud ja Korutina 2 jätkab tööd, kuna kasutatakse SupervisorJob.