Hello! Can somebody explain me this Flow statemen...
# coroutines
d
Hello! Can somebody explain me this Flow statement, I couldn’t get it as documentation is not obvious(maybe in my case):
Copy code
All exception-handling Flow operators follow the principle of exception suppression:
If the upstream flow throws an exception during its completion when the downstream exception has been thrown, the downstream exception becomes superseded and suppressed by the upstream exception, being a semantic equivalent of throwing from finally block. However, this doesn't affect the operation of the exception-handling operators, which consider the downstream exception to be the root cause and behave as if the upstream didn't throw anything.
If possible with example. Thank you!
s
Sure! This behaviour is specific to the case where the upstream throws an error after the downstream has thrown an error. In this case, the upstream error won't be able to be caught by any
catch
operators that would normally intercept errors. You can think of it as being because the exception is "too late" to be caught. Since it's in a
finally
or
onCompletion
block triggered after the flow's completion, it's being thrown after the catch operators in its path would normally have been triggered. Here's some example code.
Copy code
suspend fun main() {
  flow {
    try {
      emit("Hello!")
    } finally {
      error("upstream")
    }
  }.catch {
    println("This never happens, even though the upstream threw an error")
  }.collect {
    error("downstream")
  }
}
When you run the program, you'll see that it fails with the "upstream" exception. This corresponds to the first part of the docs:
If the upstream flow throws an exception during its completion when the downstream exception has been thrown, the downstream exception becomes superseded and suppressed by the upstream exception.
However, the
catch
section is not executed. We never see the "This never happens" line of output from the example code, even though the exception was thrown from a part of the flow that is upstream of the catch operator. This is because of the second point in the docs:
However, this doesn't affect the operation of the exception-handling operators, which consider the downstream exception to be the root cause.
d
Thank you for the explanation @Sam great answer as always!!