For Flows that are turned into AsyncSequence in Sw...
# touchlab-tools
s
For Flows that are turned into AsyncSequence in Swift using Skie, how is error handling supposed to be handled? And more specifically cancellation? The docs here mention that two-way cancellation is handled, but if there was a cancellation on the kotlin side, how does that surface on the swift side? Is the idea to to a
do { for await item in flow … } catch { here there was a cancellation on Kotlin side }
? Am I missing some part of the docs that I should look at instead?
i
You will got the
kotlin.coroutines.cancellation.CancellationException: StandaloneCoroutine was cancelled
after you cancel the job.
Copy code
job?.cancel()
        job = flow<String>{}
        .catch { e ->
                when (e) {
                    sideEffectFlow.emit("to notify the UI about the error")
                }
            }
            .onCompletion {
                if (it != null) {
                    // some error occurred
                } else {
                   // completed without error
                }
            }.launchIn(this)
f
SKIE handles the cancellation from Kotlin by cancelling the Swift task in which you loop over the converted AsyncSequence. If you need to handle that manually from Swift you should use the
withTaskCancellationHandler
. However, in most cases you don’t have to do anything because the iteration will stop on its own.
s
Perfect, thank you!
d
hi @Filip Dolník here is a case that i do not exception handling. i got the exception which is thrown in flow and the app crash. is something i did in wrong way?
f
Hi! The issue here is that this is a different kind of an exception. Only cancellation (CancellationException) is handled explicitly by SKIE. The rest is still handled by Kotlin. Kotlin handles exceptions in two different ways: either it’s converted into NSError and then the function is exported as a throwing function which must be called with the
try
syntax from Swift. The alternative is that the exception is converted into a fatal error. This is the default behavior and to get the first one you need to annotate the method that produces the error with the
@Throws
annotation and give it the specific exceptions you want to be converted. So to get exception handling in Swift you would have to annotate the last Kotlin function that is called from Swift (where the crash happens). However, in the case of Flows that is some internal function provided by a library so you can’t do that. Long story short, Flows do not support custom exception propagation (with or without SKIE). You need to handle the exception inside Kotlin and pass it to Swift in some way if needed. The common way to do this is to use the Result pattern.
🎉 2
🫶 3
d
Thank you for so detailed answer.