Sobes.tech
Middle

Ինչ եք գիտակցում Flow-ում սխալների մշակման մասին?

sobes.tech AI

Պատասխան AI-ից

Flow-ը Kotlin Coroutines-ում առաջարկում է մի քանի եղանակներ սխալների կառավարելու համար:

  1. Օպերատոր catch: Հավաքում է արտահայտություններ վերևի հոսքում և թույլ է տալիս կատարել գործողություն (օրինակ՝ գրանցում, պահեստային տվյալների վերադարձ) կամ փոխարինել հոսքը:

    flow {
        emit(1)
        throw RuntimeException("Սխալ է տեղի ունեցել")
    }.catch { e: Throwable ->
        // Սխալի մշակումը
        emit(-1) // Այլ արժեք արտանետել սխալի դեպքում
    }.collect { value ->
        // Արժեքների մշակումը
    }
    
  2. try-catch բլոկ: Կլասիկ եղանակ է արտահայտությունների մշակման համար կոդի հատվածի շուրջ, ներառյալ Flow-ի հավաքումը:

    try {
        flow {
            emit(1)
            throw RuntimeException("Սխալ է տեղի ունեցել")
        }.collect { value ->
            // Արժեքների մշակումը
        }
    } catch (e: Throwable) {
        // Սխալի մշակումը
    }
    

    Այս եղանակը բռնում է այն սխալները, որոնք տեղի են ունենում Flow-ի հավաքման ժամանակ, բայց ոչ այն սխալները, որոնք առաջացնում է ինքն էմիթենտը մինչև հավաքումը:

  3. onEach օպերատոր try-catch-ով: Եթե անհրաժեշտ է յուրաքանչյուր տարրին առանձին կերպով մշակել սխալները:

    flow {
        emit(1)
        emit(2)
        throw RuntimeException("Սխալ 2-ից հետո")
        emit(3)
    }.onEach { value ->
        try {
            // Ամեն մի տարրին մշակումը
            if (value == 2) throw IllegalArgumentException("Անվավեր արժեք 2")
        } catch (e: Throwable) {
            // Սխալի մշակումը կոնկրետ արժեքի համար
            println("Սխալ արժեք $value-ի համար: ${e.message}")
            // Կարող եք փոխանցել արտահայտությունը հետագա, եթե ուզում եք կանգնեցնել հոսքը
            throw e
        }
    }.catch { e: Throwable ->
        // Սխալների մշակումը, որոնք չեն բռնվել onEach-ում կամ այն հետո արտածված սխալները
        println("Վերջնական սխալ: ${e.message}")
    }.collect { value ->
        println("Ստացված արժեք: $value")
    }
    
  4. retry / retryWhen օպերատորներ: Դրանք թույլ են տալիս կրկնել Flow-ի աղբյուրը սխալի դեպքում:

    • retry: պարզապես կրկնում է փորձը նշված քանակով:
    • retryWhen: թույլ է տալիս սահմանել պայմանը կրկնության համար:
    var attempt = 0
    flow {
        println("Փորձ ${++attempt}")
        if (attempt < 3) throw RuntimeException("Կրկնվող փորձ")
        emit(10)
    }.retryWhen { cause, attempt ->
        // Լոգիկա՝ որոշելու, արդյոք պետք է կրկնել
        cause is RuntimeException && attempt < 3
    }.collect { value ->
        println("Հաջողություն: $value")
    }
    
  5. Անցանցում արտածված սխալները: Չմշակված սխալները կշարժվեն վերև Flow շղթայում և կարող են բռնվել try-catch բլոկում կամ catch օպերատորով:

Հիմնականը հասկանալը, որ catch օպերատորը բռնում է վերևի հոսքում սխալները: Սխալները, որոնք առաջանում են ներքևի հոսքում (downstream) catch-ից հետո, չեն բռնվում: Այդպիսի սխալների համար անհրաժեշտ է օգտագործել այլ catch կամ try-catch հավաքողը:

Ընդհանուր խորհուրդ՝ տեղադրեք սխալների մշակումը որքան հնարավոր է մոտ աղբյուրին, բայց հաշվի առեք, որ catch-ը միայն վերևի հոսքն է բռնում: