Sobes.tech
Middle

Ce metode de gestionare a erorilor în corutine cunoști?

sobes.tech AI

Răspuns de la AI

  • Utilizarea blocurilor try...catch. Metoda standard de gestionare a excepțiilor. Funcționează în interiorul corutinei.

    // Aplicarea try-catch
    suspend fun fetchData(): String {
        return try {
            // Operație care poate arunca excepție
            throw Exception("Eroare la încărcarea datelor")
            "Date încărcate cu succes"
        } catch (e: Exception) {
            "Eroare: ${e.message}"
        }
    }
    

    try...catch nu este potrivit pentru gestionarea excepțiilor necontrolate aruncate din corutinele copil, lansate într-un alt CoroutineScope.

  • CoroutineExceptionHandler. Capturează excepțiile neprocesate aruncate de corutine, care sunt lansate în acest CoroutineScope sau în CoroutineScope-urile sale copil.

    // CoroutineExceptionHandler
    val handler = CoroutineExceptionHandler { _, exception ->
        println("Excepție capturată: $exception")
    }
    
    // Aplicarea CoroutineExceptionHandler
    GlobalScope.launch(handler) {
        // Corutină care poate arunca excepție
        throw Exception("Eroare în corutină")
    }
    

    CoroutineExceptionHandler se activează doar pentru excepțiile care nu sunt gestionate de mecanismul de concurență structurată.

  • SupervisorJob și supervisorScope. Spre deosebire de un Job obișnuit, atunci când o corutină copil cu eroare determină anularea Job-ului părinte, SupervisorJob nu anulează Job-ul părinte în cazul unei erori a corutinei copil. supervisorScope creează un CoroutineScope cu SupervisorJob.

    // Utilizarea supervisorScope
    suspend fun loadMultipleData() = supervisorScope {
        val data1 = async {
            // Poate arunca excepție
            throw Exception("Eroare în datele 1")
            "Date 1"
        }
        val data2 = async {
            "Date 2"
        }
    
        // Gestionarea excepției pentru un anumit async
        try {
            println("Rezultat 1: ${data1.await()}")
        } catch (e: Exception) {
            println("Eroare la încărcarea datelor 1: ${e.message}")
        }
        println("Rezultat 2: ${data2.await()}")
    }
    

    Este folosit pentru sarcini copil independente, în cazul în care eroarea uneia nu trebuie să afecteze celelalte. Nu înlocuiește try...catch sau CoroutineExceptionHandler, ci schimbă comportamentul de propagare a excepțiilor.

  • Propagarea excepțiilor în concurența structurată. În mod implicit, o excepție în corutina copil anulează corutina părinte și toți frații săi.

    // Exemplu de propagare a excepției
    runBlocking {
        val job = launch {
            launch { // Corutină copil 1
                delay(100)
                throw Exception("Eroare în copilul 1")
            }
            launch { // Corutină copil 2
                delay(200)
                println("Copil 2 s-a finalizat")
            }
        }
        try {
            job.join()
        } catch (e: Exception) {
            println("Excepție capturată în părinte: $e")
        }
    }
    

    Acesta este comportamentul de bază al concurenței structurate, care ajută la evitarea scurgerilor de resurse și a stărilor.

  • Utilizarea async cu await(). Excepțiile aruncate în async nu se propagă automat. Ele sunt stocate în interiorul Deferred și sunt aruncate doar la apelarea await().

    // Gestionarea excepțiilor cu async/await
    suspend fun safeAsyncCall() = coroutineScope {
        val deferred = async {
            throw Exception("Eroare în async")
            "Rezultat async"
        }
    
        try {
            val result = deferred.await()
            println("Rezultat: $result")
        } catch (e: Exception) {
            println("Excepție capturată din async: ${e.message}")
        }
    }
    

    Permite tratarea selectivă a erorilor pentru fiecare sarcină asincronă.

Metodă Scop Capturează uncaught? Schimbă propagarea?
try...catch Gestionarea excepțiilor în cadrul coroutinei curente Nu Nu
CoroutineExceptionHandler Capturarea excepțiilor neprocesate în Scope Da Nu
SupervisorJob/Scope Schimbarea comportamentului de propagare a excepțiilor Nu Da
Concurența structurată Anulare automată la apariția unei erori Da Da
async + await() Propagarea întârziată a excepțiilor Nu Da (până la await)