Wasm-bindgen: JsValue::into_serde raises an error when called with undefined

Created on 20 Sep 2019  路  3Comments  路  Source: rustwasm/wasm-bindgen

Describe the Bug

When JsValue::into_serde is called on an undefined value, wasm-bindgen raises a JavaScript exception instead of returning an Err value.

Steps to Reproduce

Set up the following project:

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn hello(thing: JsValue) {
    let _: Result<i32, _> = thing.into_serde();
}

```toml
[package]
name = "oopsie"
version = "0.1.0"
edition = "2018"

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }


Build and package with `wasm-pack build --target nodejs`, launch `node` and try to call `hello` with `undefined`:
```js
let pkg = require('./pkg');
pkg.hello(undefined);

Expected Behavior

The Err variant is returned. If the target type was an Option<i32>, the deserialization could also be successful.

Actual Behavior

A JavaScript TypeError was thrown in the glue code:

> let pkg = require('./pkg');
undefined
> pkg.hello(undefined)
TypeError: "string" must be a string, Buffer, or ArrayBuffer
    at Function.byteLength (buffer.js:481:11)
    at passStringToWasm (/home/matcegla/oopsie/pkg/oopsie.js:40:25)
    at module.exports.__wbindgen_json_serialize (/home/matcegla/oopsie/pkg/oopsie.js:69:18)
    at oopsie::hello::h4722553de1adeefa (wasm-function[50]:26)
    at hello (wasm-function[131]:3)
    at Object.module.exports.hello (/home/matcegla/oopsie/pkg/oopsie.js:23:10
bug

All 3 comments

Whenever Ok(val) is encountered it's converted to JS and handed off, and whenever Err(error) is encountered an exception is thrown in JS with error.

Source

It seems expected then that a call to hello with a failed serialization would then throw a JavaScript exception.

I'm not sure if there is a way to disable this.

No, this is not this kind of conversion. The result here is a Result<i32, serde_json::Error> that comes from JsValue::into_serde that's also described here, not from wasm-bindgen macro-generated bindings(for which the source you cited would apply).

Also, serialization failure does not throw in general, but only when undefined is passed. For example, when we add the code to log the result:

> let pkg = require('./pkg');
undefined
> pkg.hello(42);
'Ok(42)'
> pkg.hello('yoyo');
'Err(Error("invalid type: string \\"yoyo\\", expected i32", line: 1, column: 6))'
> pkg.hello(null);
'Err(Error("invalid type: null, expected i32", line: 1, column: 4))'
> pkg.hello(undefined);
TypeError [ERR_INVALID_ARG_TYPE]: The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type undefined
    at Function.byteLength (buffer.js:514:11)
    at passStringToWasm (/home/matcegla/oopsie/pkg/oopsie.js:69:24)
    at module.exports.__wbindgen_json_serialize (/home/matcegla/oopsie/pkg/oopsie.js:90:18)
    at oopsie::hello::hbdd2e1f68530c309 (wasm-function[57]:26)
    at hello (wasm-function[67]:16)
    at Object.module.exports.hello (/home/matcegla/oopsie/pkg/oopsie.js:48:22)
> 

Thanks for the clear report! I've attempted to fix this in https://github.com/rustwasm/wasm-bindgen/pull/1783

Was this page helpful?
0 / 5 - 0 ratings