Sobes.tech
Middle

Wat weet je over foutafhandeling in Flow?

sobes.tech AI

Antwoord van AI

Flow in Kotlin Coroutines biedt verschillende manieren om fouten af te handelen:

  1. Operator catch: Vangt uitzonderingen op in de opwaartse stroom en maakt het mogelijk om een actie uit te voeren (bijvoorbeeld logging, het teruggeven van reservegegevens) of de stroom te vervangen.

    flow {
        emit(1)
        throw RuntimeException("Er is een fout opgetreden")
    }.catch { e: Throwable ->
        // Foutafhandeling
        emit(-1) // Een andere waarde uitgeven bij fout
    }.collect { value ->
        // Waardeverwerking
    }
    
  2. try-catch blok: Klassieke manier om uitzonderingen te behandelen rond een stuk code, inclusief het verzamelen van Flow.

    try {
        flow {
            emit(1)
            throw RuntimeException("Er is een fout opgetreden")
        }.collect { value ->
            // Waardeverwerking
        }
    } catch (e: Throwable) {
        // Foutafhandeling
    }
    

    Deze methode vangt fouten op die optreden tijdens het verzamelen van Flow, maar niet fouten die door de Flow-emitter voor het verzamelen worden veroorzaakt.

  3. Operator onEach met try-catch: Als je fouten voor elk element afzonderlijk wilt afhandelen.

    flow {
        emit(1)
        emit(2)
        throw RuntimeException("Fout na 2")
        emit(3)
    }.onEach { value ->
        try {
            // Verwerking van elk element
            if (value == 2) throw IllegalArgumentException("Ongeldige waarde 2")
        } catch (e: Throwable) {
            // Foutafhandeling voor een specifieke waarde
            println("Fout voor waarde $value: ${e.message}")
            // Fout verder gooien om de stroom te stoppen
            throw e
        }
    }.catch { e: Throwable ->
        // Afhandeling van fouten die niet in onEach worden opgevangen, of fouten die na onEach worden gegooid
        println("Eindfout: ${e.message}")
    }.collect { value ->
        println("Verzamelde waarde: $value")
    }
    
  4. Operator retry / retryWhen: Stellen je in staat om de bron van Flow opnieuw te proberen bij een fout.

    • retry: Herhaalt eenvoudig de poging een vastgesteld aantal keren.
    • retryWhen: Bepaalt de voorwaarde voor herhaling.
    var attempt = 0
    flow {
        println("Poging ${++attempt}")
        if (attempt < 3) throw RuntimeException("Herhaling")
        emit(10)
    }.retryWhen { cause, attempt ->
        // Logica om te bepalen of opnieuw geprobeerd moet worden
        cause is RuntimeException && attempt < 3
    }.collect { value ->
        println("Succes: $value")
    }
    
  5. Uitzonderingen doorgeven: Niet-gevangen fouten worden omhoog in de Flow-keten doorgegeven en kunnen worden opgevangen in een try-catch-blok rond de Flow-verzamelaar of met de catch-operator.

Het is belangrijk om te begrijpen dat de catch-operator fouten in de opwaartse stroom (upstream) opvangt. Fouten die in de neerwaartse stroom (downstream) na catch optreden, worden niet opgevangen. Voor het afhandelen van dergelijke fouten moet een andere catch onderaan de keten worden gebruikt of een try-catch rond de verzamelaar.

Algemene aanbeveling: plaats foutafhandeling zo dicht mogelijk bij de bron van de fout, indien mogelijk, maar houd er rekening mee dat catch alleen de opwaartse stroom behandelt.