Is there any way to make a catch operator which do...
# coroutines
v
Is there any way to make a catch operator which does not cancel the upstream flow when an exception occurs What currently happens is, it cancels the flow
Copy code
val flow = flowOf(1, 2, 3, 4, 5)
    .onEach { if(it % 3 == 0) throw Exception("Failed") }
    .catch { println(it) }

fun main() {
    runBlocking {
        flow.collect { println(it) }
    }
}

Output:
1
2
java.lang.Exception: Failed
How can i make catch just skip 3 So the final output becomes
Copy code
1 2 4 5
I know i can just use a tryCatch, but in my usecase, the failure can happen in any flow operator, and i dont want to cancel the flow My usecase: I have a flow which listens to
isTyping
,
isOnline
events in a messaging scenario Now if there is any error in any flow operator the upstream flow is cancelled, What i want is to just ignore that emission and let the flow continue as usual I dont want to add a try catch to every operator, but use something like the inbuilt
catch
operator which will catch any exception in the upstream flow but not cancel the upstream flow
s
No, it's not possible. You must think of the upstream flow the same way you think of an ordinary function. When it throws an exception, it exits.
d
It's not possible. The code in your example becomes this after the operators are applied:
Copy code
val flow = flow {
  for (it in listOf(1, 2, 3, 4, 5)) {
    if(it % 3 == 0) throw Exception("Failed")
    emit(it)
  }
}.catch { println(it) }
Once the exception is thrown, we can't just continue executing the code anyway, that's against Kotlin's rules. What you can do is restart the whole upstream, though: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/retry.html From the description of your use case, it looks like it might work.