From 6abacb52712036fbafa64023bc1cf13b0dacb975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Csorba?= <150924204+daniCsorbaJB@users.noreply.github.com> Date: Thu, 31 Oct 2024 15:12:56 +0100 Subject: [PATCH] update: adding information about new wasm jsexception handling (#4518) * update: adding information about new wasm jsexception handling * implementing comments for TWr review --- docs/topics/wasm/wasm-js-interop.md | 53 +++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/docs/topics/wasm/wasm-js-interop.md b/docs/topics/wasm/wasm-js-interop.md index a88b204bb7c..168aae43d95 100644 --- a/docs/topics/wasm/wasm-js-interop.md +++ b/docs/topics/wasm/wasm-js-interop.md @@ -359,7 +359,56 @@ external fun processData(data: JsArray): T ## Exception handling -The Kotlin `try-catch` expression can't catch JavaScript exceptions. +You can use Kotlin `try-catch` expression to catch JavaScript exceptions. +However, accessing specific details about the thrown value in Kotlin/Wasm isn’t possible by default. + +You can configure the `JsException` type to include the original error message and stack trace from JavaScript. +To do so, add the following compiler flag to your `build.gradle.kts` file: + +```kotlin +kotlin { + wasmJs { + compilerOptions { + freeCompilerArgs.add("-Xwasm-attach-js-exception") + } + } +} +``` + +This behavior depends on the `WebAssembly.JSTag` API, which is only available in certain browsers: + +* **Chrome:** Supported from version 115 +* **Firefox:** Supported from version 129 +* **Safari:** Not yet supported + +Here’s an example demonstrating this behavior: + +```kotlin +external object JSON { + fun parse(json: String): T +} + +fun main() { + try { + JSON.parse("an invalid JSON") + } catch (e: JsException) { + println("Thrown value is: ${e.thrownValue}") + // SyntaxError: Unexpected token 'a', "an invalid JSON" is not valid JSON + + println("Message: ${e.message}") + // Message: Unexpected token 'a', "an invalid JSON" is not valid JSON + + println("Stacktrace:") + // Stacktrace: + + // Prints the full JavaScript stack trace + e.printStackTrace() + } +} +``` + +With the `-Xwasm-attach-js-exception` flag enabled, the `JsException` type provides specific details from the JavaScript error. +Without the flag, `JsException` includes only a generic message stating that an exception was thrown while running JavaScript code. If you try to use a JavaScript `try-catch` expression to catch Kotlin/Wasm exceptions, it looks like a generic `WebAssembly.Exception` without directly accessible messages and data. @@ -381,7 +430,7 @@ Although Kotlin/Wasm interoperability shares similarities with Kotlin/JS interop | **Long** | Type corresponds to JavaScript `BigInt`. | Visible as a custom class in JavaScript. | | **Arrays** | Not supported in interop directly yet. You can use the new `JsArray` type instead. | Implemented as JavaScript arrays. | | **Other types** | Requires `JsReference<>` to pass Kotlin objects to JavaScript. | Allows the use of non-external Kotlin class types in external declarations. | -| **Exception handling** | Starting from Kotlin 2.0.0, it can catch any JavaScript exception via the `JsException` and `Throwable` types. | Can catch JavaScript `Error` via the `Throwable` type. It can catch any JavaScript exception using the `dynamic` type. | +| **Exception handling** | You can catch any JavaScript exception with the `JsException` and `Throwable` types. | Can catch JavaScript `Error` using the `Throwable` type. It can catch any JavaScript exception using the `dynamic` type. | | **Dynamic types** | Does not support the `dynamic` type. Use `JsAny` instead (see sample code below). | Supports the `dynamic` type. | > Kotlin/JS [dynamic type](dynamic-type.md) for interoperability with untyped or loosely typed objects is not