Sobes.tech
Middle

Mida teate Flow vigade töötlemisest?

sobes.tech AI

Vastus AI-lt

Kotlin Coroutines Flow pakalpo vairākus veidus, kā apstrādāt kļūdas:

  1. catch operators: Tas pārķer izņēmumus augšupējā plūsmā un ļauj veikt darbību (piemēram, reģistrēt, atgriezt rezerves datus) vai aizstāt plūsmu.

    flow {
        emit(1)
        throw RuntimeException("Radās kļūda")
    }.catch { e: Throwable ->
        // Kļūdas apstrāde
        emit(-1) // Izlaist citu vērtību kļūdas gadījumā
    }.collect { value ->
        // Vērtību apstrāde
    }
    
  2. try-catch bloks: Klasisks veids, kā apstrādāt izņēmumus apgabala kodu, ieskaitot Flow savākšanu.

    try {
        flow {
            emit(1)
            throw RuntimeException("Radās kļūda")
        }.collect { value ->
            // Vērtību apstrāde
        }
    } catch (e: Throwable) {
        // Kļūdas apstrāde
    }
    

    Šis veids pārķer kļūdas, kas rodas, savācot Flow, bet ne kļūdas, ko rada pats Flow emitētājs pirms savākšanas.

  3. onEach operators ar try-catch: Ja nepieciešams apstrādāt kļūdas katram elementam atsevišķi.

    flow {
        emit(1)
        emit(2)
        throw RuntimeException("Kļūda pēc 2")
        emit(3)
    }.onEach { value ->
        try {
            // Katras vērtības apstrāde
            if (value == 2) throw IllegalArgumentException("Nederīga vērtība 2")
        } catch (e: Throwable) {
            // Kļūdas apstrāde konkrētam value
            println("Kļūda vērtībai $value: ${e.message}")
            // Var izsviest izņēmumu tālāk, ja nepieciešams pārtraukt plūsmu
            throw e
        }
    }.catch { e: Throwable ->
        // Kļūdu apstrāde, kas nav pārķertas `onEach`, vai kļūdas, kas izsviestas pēc `onEach`
        println("Kopsavilkuma kļūda: ${e.message}")
    }.collect { value ->
        println("Vērtība savākta: $value")
    }
    
  4. retry / retryWhen operators: ļauj atkārtoti mēģināt avotu Flow, ja rodas kļūda.

    • retry: vienkārši atkārto mēģinājumu noteiktu reižu skaitu.
    • retryWhen: ļauj noteikt nosacījumu atkārtot mēģinājumu.
    var attempt = 0
    flow {
        println("Mēģinājums ${++attempt}")
        if (attempt < 3) throw RuntimeException("Atkārtots mēģinājums")
        emit(10)
    }.retryWhen { cause, attempt ->
        // Loģika, lai noteiktu, vai atkārtot
        cause is RuntimeException && attempt < 3
    }.collect { value ->
        println("Veiksme: $value")
    }
    
  5. Izņēmumu pārsūtīšana: Kļūdas, kas nav tieši pārķertas, tiks pārsūtītas uz augšu pa Flow ķēdi un tās var tikt pārķertas try-catch blokā ap Flow savākšanu vai catch operatorā.

Svarīgi saprast, ka catch operators pārķer kļūdas augšupējā plūsmā (upstream). Kļūdas, kas rodas lejupējā plūsmā (downstream) pēc catch, tās neķer. Lai apstrādātu šādas kļūdas, jāizmanto cits catch zemāk ķēdē vai try-catch ap Flow savākšanu.

Kopējā ieteikums: novietot kļūdu apstrādi pēc iespējas tuvāk kļūdas avotam, ja tas ir iespējams, bet jāņem vērā, ka catch apstrādā tikai augšupējo plūsmu.