Sobes.tech
Middle

Flow'da xatoliklarni qanday boshqarish haqida nima bilasiz?

sobes.tech AI

AIdan javob

Kotlin Coroutines ichidagi Flow xatoliklarni boshqarish uchun bir nechta usullarni taklif qiladi:

  1. catch operatori: Yuqoriga oqimdagi istisnolarni ushlaydi va harakat qilish imkonini beradi (masalan, loglash, zaxira ma'lumotlarni qaytarish) yoki oqimni o'zgartiradi.

    flow {
        emit(1)
        throw RuntimeException("Xato yuz berdi")
    }.catch { e: Throwable ->
        // Xato bilan ishlash
        emit(-1) // Xatolik bo'lsa, boshqa qiymat yuborish
    }.collect { value ->
        // Qiymatlarni ishlash
    }
    
  2. try-catch blok: Kod bo'lagi atrofida istisnolarni boshqarish uchun klassik usul, Flow yig'ish bilan birga.

    try {
        flow {
            emit(1)
            throw RuntimeException("Xato yuz berdi")
        }.collect { value ->
            // Qiymatlarni ishlash
        }
    } catch (e: Throwable) {
        // Xato bilan ishlash
    }
    

    Bu usul, Flow yig'ish vaqtida yuzaga keladigan xatoliklarni ushlaydi, lekin Flow emitters tomonidan yig'ishdan oldin yuzaga kelgan xatoliklarni ushlamaydi.

  3. onEach operatori bilan try-catch: Agar har bir element uchun xatoliklarni alohida ishlash kerak bo'lsa.

    flow {
        emit(1)
        emit(2)
        throw RuntimeException("2 dan keyingi xato")
        emit(3)
    }.onEach { value ->
        try {
            // Har bir elementni ishlash
            if (value == 2) throw IllegalArgumentException("Noto'g'ri qiymat 2")
        } catch (e: Throwable) {
            // Muayyan qiymat uchun xatolikni ishlash
            println("Qiymat $value uchun xato: ${e.message}")
            // Xatolikni uzatish, oqimni to'xtatish uchun
            throw e
        }
    }.catch { e: Throwable ->
        // onEach'dan keyin yoki onEach'dan keyin yuborilgan xatoliklarni ishlash
        println("Yakuni xato: ${e.message}")
    }.collect { value ->
        println("Yig'ilgan qiymat: $value")
    }
    
  4. retry / retryWhen operatorlari: Xatolik yuzaga kelganda, Flow manbasini takrorlash imkonini beradi.

    • retry: Faqat belgilangan sonda takrorlaydi.
    • retryWhen: Takrorlash shartini belgilash imkonini beradi.
    var attempt = 0
    flow {
        println("Urinish ${++attempt}")
        if (attempt < 3) throw RuntimeException("Takrorlash")
        emit(10)
    }.retryWhen { cause, attempt ->
        // Takrorlash uchun shartni belgilash
        cause is RuntimeException && attempt < 3
    }.collect { value ->
        println("Muvaffaqiyat: $value")
    }
    
  5. Xatoliklarni uzatish: Aniq ushlangan xatoliklar Flow zanjirida yuqoriga uzatiladi va try-catch blokida yoki catch operatori bilan ushlanishi mumkin.

Muhim: catch operatori, yuqoriga oqimdagi xatoliklarni ushlaydi. catchdan keyingi pastga oqimda (downstream) yuzaga kelgan xatoliklar ushlanmaydi. Bunday xatoliklarni boshqarish uchun, zanjirda boshqa catch yoki try-catch ishlatilishi kerak.

Umumiy tavsiya: xatoliklarni imkon qadar manbaga yaqinroq joylashtirish, lekin catch faqat yuqoriga oqimni boshqarishini unutmang.