Sobes.tech
Middle

Flow'da hata işleme hakkında ne biliyorsunuz?

sobes.tech yapay zeka

AI'dan gelen yanıt

Kotlin Coroutines içindeki Flow, hata yönetimi için birkaç yöntem sunar:

  1. catch operatörü: Yukarı akışta istisnaları yakalar ve bir işlem gerçekleştirmeye (örneğin, günlük kaydı, yedek veri döndürme) veya akışı değiştirmeye izin verir.

    flow {
        emit(1)
        throw RuntimeException("Bir hata oluştu")
    }.catch { e: Throwable ->
        // Hata işleme
        emit(-1) // Hata durumunda başka bir değer yay
    }.collect { value ->
        // Değerlerin işlenmesi
    }
    
  2. try-catch bloğu: Bir kod bloğu etrafında istisnaları yakalamak için klasik yöntem, Flow toplama dahil.

    try {
        flow {
            emit(1)
            throw RuntimeException("Bir hata oluştu")
        }.collect { value ->
            // Değerlerin işlenmesi
        }
    } catch (e: Throwable) {
        // Hata işleme
    }
    

    Bu yöntem, Flow toplama sırasında oluşan hataları yakalar, ancak Flow'un emetçisi tarafından toplamadan önce üretilen hataları yakalamaz.

  3. onEach operatörü ile try-catch: Her öğe için hataları ayrı ayrı işlemek gerekiyorsa.

    flow {
        emit(1)
        emit(2)
        throw RuntimeException("2 sonrası hata")
        emit(3)
    }.onEach { value ->
        try {
            // Her öğenin işlenmesi
            if (value == 2) throw IllegalArgumentException("Geçersiz değer 2")
        } catch (e: Throwable) {
            // Belirli bir değer için hata işleme
            println("Değer $value için hata: ${e.message}")
            // Akışı durdurmak için istisna atılabilir
            throw e
        }
    }.catch { e: Throwable ->
        // onEach'ten sonra veya onEach içinde yakalanmayan hataların işlenmesi
        println("Son hata: ${e.message}")
    }.collect { value ->
        println("Toplanan değer: $value")
    }
    
  4. retry / retryWhen operatörleri: Hata oluştuğunda Flow kaynağını tekrar denemek için kullanılır.

    • retry: Sadece belirli sayıda denemeyi tekrar eder.
    • retryWhen: Tekrar etme koşulunu belirlemeye izin verir.
    var attempt = 0
    flow {
        println("Deneme ${++attempt}")
        if (attempt < 3) throw RuntimeException("Tekrar dene")
        emit(10)
    }.retryWhen { cause, attempt ->
        // Tekrar gerekip gerekmediğine karar verme mantığı
        cause is RuntimeException && attempt < 3
    }.collect { value ->
        println("Başarı: $value")
    }
    
  5. İstisnaların iletilmesi: Açıkça yakalanmayan hatalar, Flow zincirinde yukarı doğru iletilir ve try-catch bloğu veya catch operatörü ile yakalanabilir.

Önemli: catch operatörü, yukarı akıştaki hataları yakalar. catch sonrası aşağı akışta (downstream) oluşan hatalar yakalanmaz. Bu hataları işlemek için başka bir catch veya try-catch kullanmak gerekir.

Genel öneri: Hata yönetimini mümkün olan en yakın noktaya, yani hata kaynağına yerleştirmek, ancak catch'in yalnızca yukarı akışı yakaladığını unutmamak gerekir.