What is happening? What should have happened instead?
In the open source Kable library, when upgrading to kotlinx.coroutines v1.11.0 started seeing a test fail (only on WASM) with:
AssertionError: Expected an exception of class IllegalStateException to be thrown, but was Exception: Non-Kotlin exception SecurityError: Failed to execute 'requestDevice' on 'Bluetooth': Must be handling a user gesture to show a permission request. of type 'class DOMException'
It was expected that the failure from JS would propagate from the await() as a JsException and thus would be able to be caught and examined to determine the underlying cause.
This was previously the case for both JS and WASM, but upon upgrading to v1.11.0 of kotlinx.coroutines, only on WASM the exception from JS would always propagate as Exception rather than the expected JsException.
Reproducer
JuulLabs/kable#1141 was failing in the initial upgrade commit ab302ec, until workarounds were implemented.
Anything else? (optional)
Workaround was to copy the Promise.await implementation so that JsPromiseError.toThrowable could be changed:
private fun JsPromiseError.toThrowable(): Throwable = try {
unsafeCast<JsReference<Throwable>>().get()
} catch (_: Throwable) {
- Exception("Non-Kotlin exception $this of type '${this::class}'")
+ asJsException()
}
What is happening? What should have happened instead?
In the open source Kable library, when upgrading to kotlinx.coroutines v1.11.0 started seeing a test fail (only on WASM) with:
It was expected that the failure from JS would propagate from the
await()as aJsExceptionand thus would be able to be caught and examined to determine the underlying cause.This was previously the case for both JS and WASM, but upon upgrading to v1.11.0 of kotlinx.coroutines, only on WASM the exception from JS would always propagate as
Exceptionrather than the expectedJsException.Reproducer
JuulLabs/kable#1141 was failing in the initial upgrade commit ab302ec, until workarounds were implemented.
Anything else? (optional)
Workaround was to copy the
Promise.awaitimplementation so thatJsPromiseError.toThrowablecould be changed:private fun JsPromiseError.toThrowable(): Throwable = try { unsafeCast<JsReference<Throwable>>().get() } catch (_: Throwable) { - Exception("Non-Kotlin exception $this of type '${this::class}'") + asJsException() }