Skip to content

Replace Result<T, JsValue> with Result<T, Error> #1742

Closed
@Pauan

Description

@Pauan

Motivation

As discussed in #1735, it's not idiomatic to throw JS values, like throw "foo", because that loses stack traces.

Instead it's highly recommended to always use throw new Error("foo"). In wasm-bindgen, this corresponds to Err(js_sys::Error::new("foo"))

Internally, wasm-bindgen itself follows this recommendation, however, because the wasm-bindgen (and js-sys and web-sys) APIs return Result<T, JsValue>, this encourages user functions to return Result<T, JsValue> as well, which makes it easy for users to return non-Error values:

fn foo() -> Result<(), JsValue> {
    call_some_wasm_bindgen_api()?;
    Err(JsValue::from("hi!"))
}

Proposed Solution

All wasm-bindgen APIs which return Result<T, JsValue> should instead return Result<T, Error>.

This includes wasm_bindgen(catch) (which should have a debug_assert to verify that it actually is an Error object)

This uses the static type system to make it impossible to accidentally throw non-Error types. It also is more "Rust-like", which makes the APIs easier to understand.

This is obviously a very large breaking change.

Alternatives

  • Do nothing. This is a lot less work, and isn't a breaking change, but it does mean that wasm-bindgen is encouraging bad behavior.

  • Keep Result<T, JsValue>, but put in runtime checks which verify that the Err is a js_sys::Error. This is also a lot less work, but it does have a small runtime cost, and it's surprising behavior for the user.

Metadata

Metadata

Assignees

No one assigned

    Labels

    breaking-changeTracking breaking changes for the next major version bump (if ever)web-sysIssues related to the `web-sys` crate

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions