I am having trouble understanding how the catch
operator works in a kotlin Flow
.
Here is the catch documentation
Questions:
- Why doesn't the presence of a
catch
allow theFlow
to continue upon encountering an exception, rather than complete? - Placement of the
catch
operator seems to change the behavior. Why can't I place thecatch
operator at the end of the chain to see the same result? In my example, it only executes if I place it BEFOREonEach
.
First example, placing the catch
BEFORE onEach
:
fun main() {
// Flow of lambdas that return a String (or throw an Exception)
flowOf<() -> String>({ "Hello " }, { error("error") }, { "World" })
// Map to the result of the invocation of the lambda
.map { it() }
// This line will emit the error String, but then the flow completes anyway.
// I would expect the flow to continue onto "World"
.catch { emit("[Exception caught] ") }
.onEach { println(it) }
.launchIn(GlobalScope)
}
Actual result:
Hello [Exception caught]
Expected result:
Hello [Exception caught] World
Second example, placing the catch
AFTER onEach
:
fun main() {
// Flow of lambdas that return a String (or throw an Exception)
flowOf<() -> String>({ "Hello " }, { error("error") }, { "World" })
// Map to the result of the invocation of the lambda
.map { it() }
.onEach { println(it) }
// I would expect this catch to emit, but it never gets here.
.catch { emit("[Exception caught] ") }
.launchIn(GlobalScope)
}
Actual result:
Hello
Expected result:
Hello [Exception caught] World
Or, since the onEach
happens before the catch
's emission, the catch
's emission would be ignored? In which case, the expected output would be this?:
Hello World