Is it possible to catch kotlin exception in swift ...
# kotlin-native
j
Is it possible to catch kotlin exception in swift code? (kotlin part imported as a framework)
t
Yes if cheched
j
And there is a little complication:
Copy code
suspend fun <T : Any> call(command: Command<T>): T{
// here exception can be thrown
}

fun <T : Any> callAsync(command: Command<T>, context: CoroutineContext): Deferred<T> {
        return GlobalScope.async(context) {
            call(command = command)
        }
    }
ios runs callAsync, while exception is thrown inside suspend function
t
You need @Throws annotation to make it work
j
where? idea doesn’t recognize it 🙂
Unresolved reverence Throws
j
hmm.. ok, that compiled, thanks!
But IntelliJ doesn’t recognize it
o
Maybe you have incorrect build script or due to bug your code is not recognized as native module. Can you use other pure native APIs?
s
Kotlin/Native
@Throws
annotation can’t be imported to common code. Instead you can declare it as
expect annotation class
with
actual typealias
.
k
@svyatoslav.scherbina any code example?
j
OK, I’ve added @Throws, now objc method has error param and in swift I can use try/catch. But, as actual exception is thrown asynchronously somewhere in the depths of Deferred, it isn’t catched
I’ve now added
invokeOnCompletion(onCancelling:
which receives thrown error, but app crashes nonetheless with the same error
s
@Konstantin Petrukhnov
Copy code
// Common code:
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR)
expect annotation class Throws(vararg val exceptionClasses: kotlin.reflect.KClass<out kotlin.Throwable>)

// Android code:
actual typealias Throws = kotlin.jvm.Throws

// iOS code:
actual typealias Throws = kotlin.native.Throws
👍 3
@Jaroslav
I’ve now added
invokeOnCompletion(onCancelling:
which receives thrown error, but app crashes nonetheless with the same error
Which one?
j
ios app
s
Which error?
j
suspend function throws an exception, then on ios part my callback that was given via
invokeOnCompletion(onCancelling:
get’s called, printing error shows that’s the same one that was thrown, for now everything’s ok, but then after that callback is executed, app crashes with
Uncaught Kotlin exception:
. Setting
NSSetUncaughtExceptionHandler
doesn’t help either.
and crashes with the same error that was printed inside
invokeOnCompletion(onCancelling:
s
Could you please provide exception and crash stacktraces? A sample to reproduce the issue would also be useful.
j
ok, I’ll try to make a demo app later today
s
@Throws
suspend fun anotherGreeting(): String {
This is wrong.
@Throws
annotation must be applied to the function that is called from Swift directly.
j
I’ll ad that in a minute, but I’ve tried that before - it won’t help
s
Yes, because
@Throws
annotation must be added to the function that is called from Swift and throws an exception. In your case this function seems to be
deferred.getCompleted()
.
j
yeah, but deferred is an interface, so even if I override it with mine, globalScope.async will still return original interface that has no
@throws
s
Yes, that’s why it is required to add
@Throws
wrapper for
deferred.getCompleted()
.
j
sorry, maybe I’m too green in kotlin, but how this can be done?
s
Copy code
@Throws
fun <T> getCompletedOrThrow(deferred: Deferred<T>): T = deferred.getCompleted()
j
thanks! I think I’ve got that, finally 🙂
s
You can either apply
@OptionalExpectation
(https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-optional-expectation/index.html) or declare a dummy
actual annotation class Throws
for JS.
K 1
a
Nice annotation! Thank you so much 😄
302 Views