Skip to content

JsValue::into_serde raises an error when called with undefined #1778

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
unneon opened this issue Sep 20, 2019 · 3 comments · Fixed by #1783
Closed

JsValue::into_serde raises an error when called with undefined #1778

unneon opened this issue Sep 20, 2019 · 3 comments · Fixed by #1783
Labels

Comments

@unneon
Copy link

unneon commented Sep 20, 2019

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();
}
[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:

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
@unneon unneon added the bug label Sep 20, 2019
@garrettmaring
Copy link

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.

@unneon
Copy link
Author

unneon commented Sep 21, 2019

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)
> 

alexcrichton added a commit to alexcrichton/wasm-bindgen that referenced this issue Sep 23, 2019
Turns out that `JSON.stringify(undefined)` doesn't actually return a
string, it returns `undefined`! If we're requested to serialize
`undefined` into JSON instead just interpret it as `null` which should
have the expected semantics of serving as a placeholder for `None`.

Closes rustwasm#1778
@alexcrichton
Copy link
Contributor

Thanks for the clear report! I've attempted to fix this in #1783

alexcrichton added a commit that referenced this issue Sep 25, 2019
Turns out that `JSON.stringify(undefined)` doesn't actually return a
string, it returns `undefined`! If we're requested to serialize
`undefined` into JSON instead just interpret it as `null` which should
have the expected semantics of serving as a placeholder for `None`.

Closes #1778
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants