Skip to content

Commit 6f3a9bb

Browse files
committed
Forward error messages when converting to js types
1 parent 9e2203b commit 6f3a9bb

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

tests/wasm.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use core::panic;
2+
13
use serde::{Deserialize, Serialize};
24
use tsify_next::Tsify;
35
use wasm_bindgen::prelude::*;
@@ -35,7 +37,9 @@ function validate(value, validation) {
3537
validation(value);
3638
}
3739
38-
module.exports = { validate };
40+
function noop(value) {}
41+
42+
module.exports = { validate, noop };
3943
"#)]
4044
extern "C" {
4145
#[wasm_bindgen(catch, js_name = "validate")]
@@ -49,6 +53,9 @@ extern "C" {
4953
value: SimpleData,
5054
validation: &dyn Fn(&SimpleData),
5155
) -> Result<(), JsValue>;
56+
57+
#[wasm_bindgen(catch, js_name = "noop")]
58+
pub fn do_not_serialize(value: CantBeSerialized) -> Result<(), JsValue>;
5259
}
5360

5461
#[wasm_bindgen_test]
@@ -68,3 +75,29 @@ fn test_convert_simple_value_type() {
6875
})
6976
.unwrap_throw();
7077
}
78+
79+
// Test that the error message encountered during serialization is propagated to the caller
80+
#[derive(Debug, PartialEq, Deserialize, Tsify, Clone)]
81+
#[tsify(into_wasm_abi)]
82+
struct CantBeSerialized {
83+
value: i32,
84+
}
85+
86+
impl Serialize for CantBeSerialized {
87+
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
88+
where
89+
S: serde::Serializer,
90+
{
91+
Err(serde::ser::Error::custom(
92+
"This type can't be serialized NO_SERIALIZE",
93+
))
94+
}
95+
}
96+
97+
#[wasm_bindgen_test]
98+
#[should_panic(expected = "NO_SERIALIZE")]
99+
fn test_data_that_cant_be_serialized_throws_an_appropriate_error() {
100+
let val = CantBeSerialized { value: 42 };
101+
102+
let _ = do_not_serialize(val);
103+
}

tsify-next-macros/src/wasm_bindgen.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,20 @@ fn expand_into_wasm_abi(cont: &Container) -> TokenStream {
101101

102102
#[inline]
103103
fn into_abi(self) -> Self::Abi {
104-
self.into_js().unwrap_throw().into_abi()
104+
// wasm_bindgen doesn't forward the error message from the `into_js` result.
105+
// https://github.com/rustwasm/wasm-bindgen/issues/2732
106+
// Until that issue is fixed, we don't directly use `unwrap_throw()` and instead build our
107+
// own error message.
108+
// Convert to `self.into_js().unwrap_throw().into_abi()` when fixed.
109+
match self.into_js() {
110+
Ok(js) => js.into_abi(),
111+
Err(err) => {
112+
let loc = core::panic::Location::caller();
113+
let msg = format!("(Converting type failed) {} ({}:{}:{})", err, loc.file(), loc.line(), loc.column());
114+
// In theory, `wasm_bindgen::throw_str(&msg)` should work, but the error emitted by `wasm_bindgen::throw_str` cannot be picked up by `#[should_panic(expect = ...)]` in tests, so we use a regular panic.
115+
panic!("{}", msg);
116+
}
117+
}
105118
}
106119
}
107120

@@ -115,7 +128,20 @@ fn expand_into_wasm_abi(cont: &Container) -> TokenStream {
115128
impl #impl_generics From<#ident #ty_generics> for JsValue #where_clause {
116129
#[inline]
117130
fn from(value: #ident #ty_generics) -> Self {
118-
value.into_js().unwrap_throw().into()
131+
// wasm_bindgen doesn't forward the error message from the `into_js` result.
132+
// https://github.com/rustwasm/wasm-bindgen/issues/2732
133+
// Until that issue is fixed, we don't directly use `unwrap_throw()` and instead build our
134+
// own error message.
135+
// Convert to `value.into_js().unwrap_throw().into()` when fixed.
136+
match value.into_js() {
137+
Ok(js) => js.into(),
138+
Err(err) => {
139+
let loc = core::panic::Location::caller();
140+
let msg = format!("(Converting type failed) {} ({}:{}:{})", err, loc.file(), loc.line(), loc.column());
141+
// In theory, `wasm_bindgen::throw_str(&msg)` should work, but the error emitted by `wasm_bindgen::throw_str` cannot be picked up by `#[should_panic(expect = ...)]` in tests, so we use a regular panic.
142+
panic!("{}", msg);
143+
}
144+
}
119145
}
120146
}
121147
}

0 commit comments

Comments
 (0)