DeepMedia logo
Open Source

Search...

Other versions of this page

Improve this page on GitHub

Search

Exceptions

Whenever a @Knee callable throws, the exception is thrown on the other side of the bridge.

kotlin logokotlin
// Kotlin/Native @Knee fun throwSomething() { error("Something went wrong") } // Kotlin/JVM val failure = runCatching { throwSomething() }.exceptionOrNull() checkNotNull(failure) check(failure.message == "Something went wrong")

Transparency

By default, exceptions are not serializable and can't pass the JNI bridge (a jthrowable is not a Throwable!). However, Knee strives to represents exception in the most transparent way, by reconstructing them with appropriate type and parameters.

Message preservation

Whenever possible, the exception message is preserved, as can be seen in the example above.

Type preservation

Some common types are preserved. For example, a kotlin.coroutines.cancellation.CancellationException in the backend will be re-thrown as a java.util.concurrent.CancellationException in the frontend.

Instance preservation

In some occasions, especially when lambdas are involved, the same exception can cross the JNI interface twice. Consider the following example:

kotlin logokotlin
// Native @KneeInterface typealias StringMapper = (String) -> String @Knee fun mapString(source: String, mapper: StringMapper): String { return mapper(source) }

The JVM consumer code may try to mapString, but throw an exception:

kotlin logokotlin
mapString("Hello") { throw IllegalStateException("Something went wrong") }

In this scenario, the IllegalStateException is thrown from the JVM, rethrown on the K/N side when invoking mapper, and finally rethrown on the JVM side when mapString returns. That exception will be exactly the same instance, meaning that you could check they're the same with ===.

While this may seem useless, many commonly used functions (notably, Flow.collectWhile) rely on these checks and can only work when such mechanism is in place.

Custom exceptions

You may also use custom exceptions, as long as they were properly annotated as classes.

kotlin logokotlin
@KneeClass class CustomException @Knee constructor(message: String) : RuntimeException(message) { @Knee override val message: String? get() = super.message }

Whenever a CustomException is thrown inside a Knee invocation, the runtime serializes it and creates a copy for the other side of the JNI interface! You can also annotate other functions or properties for them to be exposed to JVM.

Subscribe to the DeepMedia Newsletter

The latest news about DeepMedia products, open source projects and software development at our company.

By clicking “Subscribe”, you agree that DeepMedia may use your email address to send you newsletters, including commercial communications, and to process your personal data for this purpose. You agree that DeepMedia may process said data using third-party services for this purpose in accordance with the DeepMedia Privacy Policy. You can revoke this consent at any time using the unsubscribe link included in each email or by writing at contact@deepmedia.io.