Sobes.tech
Middle

Milyen hibakezelési módszereket ismersz a korutinokban?

sobes.tech MI

Válasz az MI-től

  • A try...catch blokkok használata. Az exception kezelés standard módja. Belül működik a coroutine-on.

    // try-catch alkalmazása
    suspend fun fetchData(): String {
        return try {
            // Opeáció, ami kivételt dobhat
            throw Exception("Adatok betöltése közben hiba")
            "Adatok sikeresen betöltve"
        } catch (e: Exception) {
            "Hiba: ${e.message}"
        }
    }
    

    A try...catch nem alkalmas a gyermek coroutine-kból származó, nem kezelt kivételek kezelésére, amelyek más CoroutineScope-ban futnak.

  • CoroutineExceptionHandler. Elkapja a nem kezelt kivételeket, amelyeket a coroutine-ok dobnak, ha azok ebben a CoroutineScope-ban vagy annak gyermek scope-jaiban futnak.

    // CoroutineExceptionHandler
    val handler = CoroutineExceptionHandler { _, exception ->
        println("Elkapott kivétel: $exception")
    }
    
    // CoroutineExceptionHandler alkalmazása
    GlobalScope.launch(handler) {
        // Coroutine, ami kivételt dobhat
        throw Exception("Hiba a coroutine-ban")
    }
    

    A CoroutineExceptionHandler csak azokhoz az esetekhez aktiválódik, amikor a kivételeket nem kezeli a strukturált konkurencia mechanizmusa.

  • SupervisorJob és supervisorScope. Ellentétben a szokásos Job-bal, ha egy gyermek coroutine hibával jár, az nem okozza a szülő Job-jának törlését. A supervisorScope egy CoroutineScope-t hoz létre SupervisorJob-bal.

    // supervisorScope használata
    suspend fun loadMultipleData() = supervisorScope {
        val data1 = async {
            // Hibát dobhat
            throw Exception("Hiba az adatok 1-ben")
            "Adatok 1"
        }
        val data2 = async {
            "Adatok 2"
        }
    
        // Hibakezelés egy adott async esetén
        try {
            println("Eredmény 1: ${data1.await()}")
        } catch (e: Exception) {
            println("Hiba az adatok 1 betöltésekor: ${e.message}")
        }
        println("Eredmény 2: ${data2.await()}")
    }
    

    Ez független gyermek feladatokra használható, ahol egy hiba nem befolyásolja a többit. Nem helyettesíti a try...catch-t vagy a CoroutineExceptionHandler-t, hanem megváltoztatja a kivételek terjedésének viselkedését.

  • A kivételek terjedése a strukturált konkurenciában. Alapértelmezés szerint, ha egy gyermek coroutine kivételt dob, az az anya coroutine-t és annak összes testvérét is törli.

    // Kivétel terjedésének példája
    runBlocking {
        val job = launch {
            launch { // Gyermek coroutine 1
                delay(100)
                throw Exception("Hiba a gyermek 1-ben")
            }
            launch { // Gyermek coroutine 2
                delay(200)
                println("Gyermek 2 befejeződött")
            }
        }
        try {
            job.join()
        } catch (e: Exception) {
            println("Kezelő kivétel az anya coroutine-ban: $e")
        }
    }
    

    Ez a strukturált konkurencia alap viselkedése, amely segít elkerülni az erőforrás szivárgásokat és állapotokat.

  • Az async és await() használata. Az async-ban dobott kivételek nem terjednek automatikusan. Ezek a Deferred-ben tárolódnak, és csak az await() hívásakor dobódnak ki.

    // Kivételkezelés async/await segítségével
    suspend fun safeAsyncCall() = coroutineScope {
        val deferred = async {
            throw Exception("Hiba az async-ben")
            "Async eredmény"
        }
    
        try {
            val result = deferred.await()
            println("Eredmény: $result")
        } catch (e: Exception) {
            println("Kivétel elkapva az async-ből: ${e.message}")
        }
    }
    

    Ez lehetővé teszi az egyes aszinkron feladatok hibáinak szelektív kezelését.

Módszer Cél Uncaught-ot kezel? Terjedést módosít?
try...catch Kivételkezelés a jelenlegi coroutine-on belül Nem Nem
CoroutineExceptionHandler Nem kezelt kivételek elfogása Scope-ben Igen Nem
SupervisorJob/Scope A kivételek terjedésének viselkedésének módosítása Nem Igen
Strukturált konkurencia Automatikus törlés hiba esetén Igen Igen
async + await() Késleltetett kivétel terjesztés Nem Igen (az await-ig)