taer
04/28/2020, 11:14 PMBroadcastChannel<T>.asFlow()
The docs state: `
If the flow consumer fails with an exception, subscription is cancelled.
I have a
broadcastChannel.asFlow().onCompletion{ printSomething } .map { codeThatThrowsException }.catch { print MessageAboutError } . collect { collector}
The onCompletion fires, then the catch. Afterwards, the collect never sees a new message.. I just added the onComplete to validate. I expected the .catch
to handle the error so the flow doesn't get canceled. I can easily fix the codeThatThrowsException
but want to catch unexpected errors in the future. It looks like the downstream catch doesn't get a chance to handle the error prior to the upstream channel getting unsubscribed fromZach Klippenstein (he/him) [MOD]
04/28/2020, 11:18 PMcatch
will catch errors flowing downstream, and can stop them from flowing further downstream, emit other items downstream, etc. You could use catch
, for example, to “resubscribe” upstream when an error occurs.taer
04/28/2020, 11:24 PMoctylFractal
04/29/2020, 12:24 AMtry/catch
that codetaer
04/29/2020, 12:27 AMcatch
to operate onoctylFractal
04/29/2020, 12:29 AMretry
which will do a re-collect on error, but the thing is that doing it outside of the operation means that all the catch/retry
operator knows is that something threw an exception, and stopped all collection. retry
will call the internal collect(FlowCollector)
again with the same setup, but that may not result in perfect resumption of your code where it was, or you might miss some valuestaer
04/29/2020, 12:36 AMoctylFractal
04/29/2020, 12:48 AMcatch
operator cannot see the body of a flow {}
or map {}
, so it cannot catch the operation and resume right after it -- there is no way for catch
to "wrap" the error I have introduced here. instead, catch can only get the error after the entire method has be removed from the call stack, and it also tracks each emission to check if it came from downstreamretry
is effectively wrapping a do { ...} while(precondition)
around the whole outer try-catch
taer
04/29/2020, 1:08 AMmap
in that gist would be just a function call that gets wrapped inside the call the println
in your exampleoctylFractal
04/29/2020, 1:14 AMmap { "Label: $it" }
after the catch
, it would essentially be println("Label: Something?")
, etc.val value = "Label: Something?"
try {
println(value)
} catch (e) {
downstream = e
throw e
}
val value2 = "Label: " + if (Math.random() < 1.0) {
error("Boo!")
} else { "Another thing!" }
try {
println(value2)
} catch (e) {
downstream = e
throw e
}
i.e., the error does get caught by the outer thing properly, but it still doesn't allow each map
to be individually wrapped by catch