Есть ли способ отловить исключения, созданные в flattenMerge ()? - PullRequest
1 голос
/ 23 января 2020

Пример игровой площадки

Учитывая этот код, исключение, выброшенное в getRecords(), не попадает в testFlattenMerge() - разве оно не должно быть перехватываемым? Кроме того, в getPeople() может быть поймано исключение, которое заставляет flattenMerge() работать должным образом, но оно печатает "Оказавшись в людях" до того, как будут напечатаны какие-либо числа, а не после 64, как я ожидается. Это правильное поведение? Я не могу полностью соответствовать моей ментальной модели flattenMerge() вокруг этого.

import kotlin.reflect.KProperty
import kotlin.system.measureTimeMillis
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.*

fun getRecords(id: Int) = flow {
    repeat(5) { emit("A record for $id") }
    if (id == 6) throw RuntimeException("Anything but #6!")
    repeat(5) { emit("A record for $id") }
}

fun getPeople() = flow {
    repeat(10) { emit(getRecords(it)) }
    // repeat(10) { emit(getRecords(it).catch{ println("Caught in getPeople()")}) } // This works, but it prints /before/ any cnt lines...?
}

suspend fun testFlattenMerge() {
    println ("Merge with flattenMerge()")
    var cnt = 0
    val flowOfFlows = getPeople()
    flowOfFlows.catch{ println("Caught before flattenMerge")}
        .flattenMerge()
        .catch{ println("Caught after flattenMerge")}
        .collect {
            println("${cnt++}") // Without catching inside getPeople() this stops at 64
        }
}

suspend fun testManualMerge() {
    println("Merge manually")
    var cnt = 0    
    repeat(10) {
        getRecords(it).catch{ println("Caught in manual merge") }
            .collect {
                println("${cnt++}") // This goes up to 94, as expected
            }
    }
}

fun main() = runBlocking {
    testFlattenMerge()
    testManualMerge()
}
...