Sobes.tech
Middle

Čo viete o spracovaní chýb vo Flow?

sobes.tech AI

Odpoveď od AI

Flow v Kotlin Coroutines poskytuje niekoľko spôsobov spracovania chýb:

  1. Operátor catch: Zachytáva výnimky v stúpajúcom toku a umožňuje vykonať akciu (napríklad logovanie, návrat záložných údajov) alebo nahradiť tok.

    flow {
        emit(1)
        throw RuntimeException("Vyskytla sa chyba")
    }.catch { e: Throwable ->
        // Spracovanie chyby
        emit(-1) // Vypustenie inej hodnoty pri chybe
    }.collect { value ->
        // Spracovanie hodnôt
    }
    
  2. Blok try-catch: Klasický spôsob spracovania výnimiek okolo časti kódu, vrátane zberu Flow.

    try {
        flow {
            emit(1)
            throw RuntimeException("Vyskytla sa chyba")
        }.collect { value ->
            // Spracovanie hodnôt
        }
    } catch (e: Throwable) {
        // Spracovanie chyby
    }
    

    Tento spôsob zachytáva chyby, ktoré nastanú pri zbere Flow, ale nie chyby spôsobené samotným emitentom Flow pred zberom.

  3. Operátor onEach s try-catch: Ak je potrebné spracovať chyby pre každý prvok zvlášť.

    flow {
        emit(1)
        emit(2)
        throw RuntimeException("Chyba po 2")
        emit(3)
    }.onEach { value ->
        try {
            // Spracovanie každého prvku
            if (value == 2) throw IllegalArgumentException("Neplatná hodnota 2")
        } catch (e: Throwable) {
            // Spracovanie chyby pre konkrétnu hodnotu
            println("Chyba pre hodnotu $value: ${e.message}")
            // Môžete znovu vyhodiť výnimku, ak chcete zastaviť tok
            throw e
        }
    }.catch { e: Throwable ->
        // Spracovanie chýb, ktoré neboli zachytené v onEach, alebo chýb, ktoré boli vyhodené po onEach
        println("Konečná chyba: ${e.message}")
    }.collect { value ->
        println("Zbieraná hodnota: $value")
    }
    
  4. Operátor retry / retryWhen: Umožňujú opakovať zdroj Flow pri výskyte chyby.

    • retry: jednoducho opakuje pokus stanovený početkrát.
    • retryWhen: umožňuje určiť podmienku pre opakovanie.
    var attempt = 0
    flow {
        println("Pokus ${++attempt}")
        if (attempt < 3) throw RuntimeException("Opakovaná snaha")
        emit(10)
    }.retryWhen { cause, attempt ->
        // Logika pre určenie, či treba opakovať
        cause is RuntimeException && attempt < 3
    }.collect { value ->
        println("Úspech: $value")
    }
    
  5. Preposielanie výnimiek: Chyby, ktoré nie sú výslovne zachytené, budú preposlané vyššie po reťazci Flow a môžu byť zachytené v bloku try-catch okolo zberača Flow alebo operátorom catch.

Je dôležité pochopiť, že operátor catch zachytáva chyby v stúpajúcom toku (upstream). Chyby, ktoré vznikajú v klesajúcom toku (downstream) po catch, nie sú zachytené. Pre spracovanie takýchto chýb je potrebné použiť iný catch nižšie v reťazci alebo try-catch okolo zberača.

Všeobecná rada: umiestnite spracovanie chýb čo najbližšie ku zdroju chyby, ak je to možné, ale majte na pamäti, že catch spracováva iba stúpajúci tok.