Sobes.tech
Middle

Šta znate o obradi grešaka u Flow?

sobes.tech АИ

Одговор од АИ

Flow u Kotlin Coroutines pruža nekoliko načina za rukovanje greškama:

  1. Operator catch: Hvata izuzetke u uzlaznom toku i omogućava izvršenje radnje (npr. logovanje, vraćanje rezervnih podataka) ili zamenu toka.

    flow {
        emit(1)
        throw RuntimeException("Došlo je do greške")
    }.catch { e: Throwable ->
        // Obrada greške
        emit(-1) // Emitovanje druge vrednosti u slučaju greške
    }.collect { value ->
        // Obrada vrednosti
    }
    
  2. Blok try-catch: Klasičan način obrade izuzetaka oko dela koda, uključujući prikupljanje Flow.

    try {
        flow {
            emit(1)
            throw RuntimeException("Došlo je do greške")
        }.collect { value ->
            // Obrada vrednosti
        }
    } catch (e: Throwable) {
        // Obrada greške
    }
    

    Ovaj način hvata greške koje nastaju prilikom prikupljanja Flow, ali ne i greške koje prouzrokuje sam emiter Flow pre prikupljanja.

  3. Operator onEach sa try-catch: Ako je potrebno obraditi greške za svaki element posebno.

    flow {
        emit(1)
        emit(2)
        throw RuntimeException("Greška posle 2")
        emit(3)
    }.onEach { value ->
        try {
            // Obrada svakog elementa
            if (value == 2) throw IllegalArgumentException("Nevažeća vrednost 2")
        } catch (e: Throwable) {
            // Obrada greške za konkretan value
            println("Greška za vrednost $value: ${e.message}")
            // Možete proslediti izuzetak dalje ako želite da zaustavite tok
            throw e
        }
    }.catch { e: Throwable ->
        // Obrada grešaka koje nisu uhvaćene u onEach ili grešaka koje su bačene nakon onEach
        println("Konačna greška: ${e.message}")
    }.collect { value ->
        println("Sakupljena vrednost: $value")
    }
    
  4. Operator retry / retryWhen: Omogućavaju ponovni pokušaj izvora Flow pri pojavi greške.

    • retry: jednostavno ponavlja pokušaj zadati broj puta.
    • retryWhen: omogućava definisanje uslova za ponovni pokušaj.
    var attempt = 0
    flow {
        println("Pokušaj ${++attempt}")
        if (attempt < 3) throw RuntimeException("Pokušaj ponovo")
        emit(10)
    }.retryWhen { cause, attempt ->
        // Logika za određivanje da li treba ponoviti
        cause is RuntimeException && attempt < 3
    }.collect { value ->
        println("Uspeh: $value")
    }
    
  5. Prosleđivanje izuzetaka: Greške koje nisu eksplicitno uhvaćene biće prosleđene na viši nivo u lancu Flow i mogu biti uhvaćene u bloku try-catch oko sakupljača Flow ili operatorom catch.

Važno je razumeti da operator catch hvata greške u uzlaznom toku (upstream). Greške koje nastaju u silaznom toku (downstream) nakon catch, nisu uhvaćene. Za obradu takvih grešaka, potrebno je koristiti drugi catch niže u lancu ili try-catch oko sakupljača.

Opšti savet: postavite obradu grešaka što bliže izvoru greške, ako je to moguće, ali imajte na umu da catch obrađuje samo uzlazni tok.