I'm having troubles understanding the exception ha...
# coroutines
m
I'm having troubles understanding the exception handling in the flow. Could someone explain why the throwable completes the flow even with the 
catch { }
 in the chain? If I'd want to have a infinite flow I must handle the exceptions with 
try catch
 in the lambdas because flow will close after any exception "leaking" to the stream, right? Or is there a way to do some explicit recovery from the exception? Example code: only 
0
 will be emitted, next emit 
1
 is never executed due to flow completion after exception.
Copy code
flow {
    emit(0)
    emit(1) // never executed
}
    .onEach { if (it == 0) throw Throwable() }
    .catch { println(it) } // catch and ignore
    .collect()
so in order for this code to work as expected I'd have to add 
try catch
 inside 
onEach
a
Each call to emit in the source flow results in one call to the onEach block below it before the emit call returns. As far as the source flow is concerned,
emit(0)
threw the exception. The
.catch {}
operator surrounds the call to collect for its source, so the position of execution in the source flow is already gone by the time the catch operator's block runs
🙏 1
m
I don't know why, but I always instinctively thought that catch would prevent the upstream from blowing up. I think it could be outlined a bit more clear in the official docs
after thinking it through it does make sense
a
m
I was thinking about those docs https://kotlinlang.org/docs/flow.html#flow-exceptions That information is for sure coded somewhere in that text, but I failed to deduce it and later caught it in unit tests when playing around
a
This post is a good explanation of the mental model https://code.cash.app/rx-to-coroutines-concepts-cold-flows
The behavior of catch is kind of intrinsic to what flows are at a fundamental level