Skip to content

Commit

Permalink
Merge pull request #36 from siefkenj/bettererror
Browse files Browse the repository at this point in the history
Forward error messages when converting to js types
  • Loading branch information
siefkenj authored Apr 30, 2024
2 parents 9e2203b + 110d3d1 commit 2492b09
Show file tree
Hide file tree
Showing 10 changed files with 299 additions and 15 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# tsify-next Changelog

## v0.5.3

- Propagate errors encountered during serialization.
- More fixes for missing `From` trait implementations.

## v0.5.2

- Fix missing trait bounds for implemented `From` traits.
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tsify-next"
version = "0.5.2"
version = "0.5.3"
edition = "2021"
authors = [
"Madono Haru <[email protected]>",
Expand All @@ -14,7 +14,7 @@ keywords = ["wasm", "wasm-bindgen", "typescript"]
categories = ["wasm"]

[dependencies]
tsify-next-macros = { path = "tsify-next-macros", version = "0.5.2" }
tsify-next-macros = { path = "tsify-next-macros", version = "0.5.3" }
wasm-bindgen = { version = "0.2.86", optional = true }
serde = { version = "1.0", optional = true }
serde_json = { version = "1.0", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Click to show Cargo.toml.

```toml
[dependencies]
tsify-next = "0.5.2"
tsify-next = "0.5.3"
serde = { version = "1.0", features = ["derive"] }
wasm-bindgen = { version = "0.2" }
```
Expand Down
58 changes: 56 additions & 2 deletions tests/expand/borrow.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,34 @@ const _: () = {
type Abi = <JsType as IntoWasmAbi>::Abi;
#[inline]
fn into_abi(self) -> Self::Abi {
self.into_js().unwrap_throw().into_abi()
match self.into_js() {
Ok(js) => js.into_abi(),
Err(err) => {
let loc = core::panic::Location::caller();
let msg = {
let res = ::alloc::fmt::format(
format_args!(
"(Converting type failed) {0} ({1}:{2}:{3})", err, loc
.file(), loc.line(), loc.column(),
),
);
res
};
{
#[cold]
#[track_caller]
#[inline(never)]
#[rustc_const_panic_str]
#[rustc_do_not_const_check]
const fn panic_cold_display<T: ::core::fmt::Display>(
arg: &T,
) -> ! {
::core::panicking::panic_display(arg)
}
panic_cold_display(&msg);
};
}
}
}
}
impl<'a> OptionIntoWasmAbi for Borrow<'a>
Expand All @@ -210,7 +237,34 @@ const _: () = {
{
#[inline]
fn from(value: Borrow<'a>) -> Self {
value.into_js().unwrap_throw().into()
match value.into_js() {
Ok(js) => js.into(),
Err(err) => {
let loc = core::panic::Location::caller();
let msg = {
let res = ::alloc::fmt::format(
format_args!(
"(Converting type failed) {0} ({1}:{2}:{3})", err, loc
.file(), loc.line(), loc.column(),
),
);
res
};
{
#[cold]
#[track_caller]
#[inline(never)]
#[rustc_const_panic_str]
#[rustc_do_not_const_check]
const fn panic_cold_display<T: ::core::fmt::Display>(
arg: &T,
) -> ! {
::core::panicking::panic_display(arg)
}
panic_cold_display(&msg);
};
}
}
}
}
impl<'a> FromWasmAbi for Borrow<'a>
Expand Down
58 changes: 56 additions & 2 deletions tests/expand/generic_enum.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,34 @@ const _: () = {
type Abi = <JsType as IntoWasmAbi>::Abi;
#[inline]
fn into_abi(self) -> Self::Abi {
self.into_js().unwrap_throw().into_abi()
match self.into_js() {
Ok(js) => js.into_abi(),
Err(err) => {
let loc = core::panic::Location::caller();
let msg = {
let res = ::alloc::fmt::format(
format_args!(
"(Converting type failed) {0} ({1}:{2}:{3})", err, loc
.file(), loc.line(), loc.column(),
),
);
res
};
{
#[cold]
#[track_caller]
#[inline(never)]
#[rustc_const_panic_str]
#[rustc_do_not_const_check]
const fn panic_cold_display<T: ::core::fmt::Display>(
arg: &T,
) -> ! {
::core::panicking::panic_display(arg)
}
panic_cold_display(&msg);
};
}
}
}
}
impl<T, U> OptionIntoWasmAbi for GenericEnum<T, U>
Expand All @@ -216,7 +243,34 @@ const _: () = {
{
#[inline]
fn from(value: GenericEnum<T, U>) -> Self {
value.into_js().unwrap_throw().into()
match value.into_js() {
Ok(js) => js.into(),
Err(err) => {
let loc = core::panic::Location::caller();
let msg = {
let res = ::alloc::fmt::format(
format_args!(
"(Converting type failed) {0} ({1}:{2}:{3})", err, loc
.file(), loc.line(), loc.column(),
),
);
res
};
{
#[cold]
#[track_caller]
#[inline(never)]
#[rustc_const_panic_str]
#[rustc_do_not_const_check]
const fn panic_cold_display<T: ::core::fmt::Display>(
arg: &T,
) -> ! {
::core::panicking::panic_display(arg)
}
panic_cold_display(&msg);
};
}
}
}
}
impl<T, U> FromWasmAbi for GenericEnum<T, U>
Expand Down
116 changes: 112 additions & 4 deletions tests/expand/generic_struct.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,34 @@ const _: () = {
type Abi = <JsType as IntoWasmAbi>::Abi;
#[inline]
fn into_abi(self) -> Self::Abi {
self.into_js().unwrap_throw().into_abi()
match self.into_js() {
Ok(js) => js.into_abi(),
Err(err) => {
let loc = core::panic::Location::caller();
let msg = {
let res = ::alloc::fmt::format(
format_args!(
"(Converting type failed) {0} ({1}:{2}:{3})", err, loc
.file(), loc.line(), loc.column(),
),
);
res
};
{
#[cold]
#[track_caller]
#[inline(never)]
#[rustc_const_panic_str]
#[rustc_do_not_const_check]
const fn panic_cold_display<T: ::core::fmt::Display>(
arg: &T,
) -> ! {
::core::panicking::panic_display(arg)
}
panic_cold_display(&msg);
};
}
}
}
}
impl<T> OptionIntoWasmAbi for GenericStruct<T>
Expand All @@ -215,7 +242,34 @@ const _: () = {
{
#[inline]
fn from(value: GenericStruct<T>) -> Self {
value.into_js().unwrap_throw().into()
match value.into_js() {
Ok(js) => js.into(),
Err(err) => {
let loc = core::panic::Location::caller();
let msg = {
let res = ::alloc::fmt::format(
format_args!(
"(Converting type failed) {0} ({1}:{2}:{3})", err, loc
.file(), loc.line(), loc.column(),
),
);
res
};
{
#[cold]
#[track_caller]
#[inline(never)]
#[rustc_const_panic_str]
#[rustc_do_not_const_check]
const fn panic_cold_display<T: ::core::fmt::Display>(
arg: &T,
) -> ! {
::core::panicking::panic_display(arg)
}
panic_cold_display(&msg);
};
}
}
}
}
impl<T> FromWasmAbi for GenericStruct<T>
Expand Down Expand Up @@ -460,7 +514,34 @@ const _: () = {
type Abi = <JsType as IntoWasmAbi>::Abi;
#[inline]
fn into_abi(self) -> Self::Abi {
self.into_js().unwrap_throw().into_abi()
match self.into_js() {
Ok(js) => js.into_abi(),
Err(err) => {
let loc = core::panic::Location::caller();
let msg = {
let res = ::alloc::fmt::format(
format_args!(
"(Converting type failed) {0} ({1}:{2}:{3})", err, loc
.file(), loc.line(), loc.column(),
),
);
res
};
{
#[cold]
#[track_caller]
#[inline(never)]
#[rustc_const_panic_str]
#[rustc_do_not_const_check]
const fn panic_cold_display<T: ::core::fmt::Display>(
arg: &T,
) -> ! {
::core::panicking::panic_display(arg)
}
panic_cold_display(&msg);
};
}
}
}
}
impl<T> OptionIntoWasmAbi for GenericNewtype<T>
Expand All @@ -478,7 +559,34 @@ const _: () = {
{
#[inline]
fn from(value: GenericNewtype<T>) -> Self {
value.into_js().unwrap_throw().into()
match value.into_js() {
Ok(js) => js.into(),
Err(err) => {
let loc = core::panic::Location::caller();
let msg = {
let res = ::alloc::fmt::format(
format_args!(
"(Converting type failed) {0} ({1}:{2}:{3})", err, loc
.file(), loc.line(), loc.column(),
),
);
res
};
{
#[cold]
#[track_caller]
#[inline(never)]
#[rustc_const_panic_str]
#[rustc_do_not_const_check]
const fn panic_cold_display<T: ::core::fmt::Display>(
arg: &T,
) -> ! {
::core::panicking::panic_display(arg)
}
panic_cold_display(&msg);
};
}
}
}
}
impl<T> FromWasmAbi for GenericNewtype<T>
Expand Down
4 changes: 4 additions & 0 deletions tests/expandtest.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//! Generates expanded code for tests in `tests/expand/` directory.
//! To update the expected output, run with `MACROTEST=overwrite cargo test`
//! or delete the `.expanded.rs` files.
#[test]
fn expandtest() {
macrotest::expand_args("tests/expand/*.rs", ["--features", "tsify-next/json"]);
Expand Down
35 changes: 34 additions & 1 deletion tests/wasm.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::panic;

use serde::{Deserialize, Serialize};
use tsify_next::Tsify;
use wasm_bindgen::prelude::*;
Expand Down Expand Up @@ -35,7 +37,9 @@ function validate(value, validation) {
validation(value);
}
module.exports = { validate };
function noop(value) {}
module.exports = { validate, noop };
"#)]
extern "C" {
#[wasm_bindgen(catch, js_name = "validate")]
Expand All @@ -49,6 +53,9 @@ extern "C" {
value: SimpleData,
validation: &dyn Fn(&SimpleData),
) -> Result<(), JsValue>;

#[wasm_bindgen(catch, js_name = "noop")]
pub fn do_not_serialize(value: CantBeSerialized) -> Result<(), JsValue>;
}

#[wasm_bindgen_test]
Expand All @@ -68,3 +75,29 @@ fn test_convert_simple_value_type() {
})
.unwrap_throw();
}

// Test that the error message encountered during serialization is propagated to the caller
#[derive(Debug, PartialEq, Deserialize, Tsify, Clone)]
#[tsify(into_wasm_abi)]
struct CantBeSerialized {
value: i32,
}

impl Serialize for CantBeSerialized {
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
Err(serde::ser::Error::custom(
"This type can't be serialized NO_SERIALIZE",
))
}
}

#[wasm_bindgen_test]
#[should_panic(expected = "NO_SERIALIZE")]
fn test_data_that_cant_be_serialized_throws_an_appropriate_error() {
let val = CantBeSerialized { value: 42 };

let _ = do_not_serialize(val);
}
2 changes: 1 addition & 1 deletion tsify-next-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tsify-next-macros"
version = "0.5.2"
version = "0.5.3"
edition = "2021"
authors = [
"Madono Haru <[email protected]>",
Expand Down
Loading

0 comments on commit 2492b09

Please sign in to comment.