Handle deserialize errors without panic (#2664)

* Handle deserialize errors rather than panic

* don't clone event data for deserialization in debug or release mode

---------

Co-authored-by: Evan Almloff <evanalmloff@gmail.com>
This commit is contained in:
Wesley McCannandEvan Almloff authored and GitHub committed 2024-07-22 12:20:15 -05:00
1 parent ba64ee04c2
commit 5bdb147afd
3 files changed
+14 -43

No files matched your search

Generated
-20
View File
@@ -2835,7 +2835,6 @@ dependencies = [
"rfd", "rfd",
"rustversion", "rustversion",
"serde", "serde",
"serde-value",
"serde_json", "serde_json",
"serde_repr", "serde_repr",
"tokio", "tokio",
@@ -6757,15 +6756,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "ordered-float"
version = "2.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c"
dependencies = [
"num-traits",
]
[[package]] [[package]]
name = "ordered-stream" name = "ordered-stream"
version = "0.2.0" version = "0.2.0"
@@ -8501,16 +8491,6 @@ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]]
name = "serde-value"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
dependencies = [
"ordered-float",
"serde",
]
[[package]] [[package]]
name = "serde-wasm-bindgen" name = "serde-wasm-bindgen"
version = "0.5.0" version = "0.5.0"
+1 -3
View File
@@ -25,7 +25,6 @@ euclid = "0.22.7"
enumset = "1.1.2" enumset = "1.1.2"
keyboard-types = { version = "0.7", default-features = false } keyboard-types = { version = "0.7", default-features = false }
async-trait = { version = "0.1.58", optional = true } async-trait = { version = "0.1.58", optional = true }
serde-value = { version = "0.7.0", optional = true }
tokio = { workspace = true, features = ["fs", "io-util"], optional = true } tokio = { workspace = true, features = ["fs", "io-util"], optional = true }
rfd = { version = "0.14", optional = true } rfd = { version = "0.14", optional = true }
futures-channel = { workspace = true } futures-channel = { workspace = true }
@@ -72,8 +71,7 @@ serialize = [
"dep:serde_repr", "dep:serde_repr",
"euclid/serde", "euclid/serde",
"keyboard-types/serde", "keyboard-types/serde",
"dioxus-core/serialize", "dioxus-core/serialize"
"serde-value",
] ]
mounted = [ mounted = [
"web-sys?/Element", "web-sys?/Element",
+13 -20
View File
@@ -24,7 +24,7 @@ impl<'de> Deserialize<'de> for HtmlEvent {
element: ElementId, element: ElementId,
name: String, name: String,
bubbles: bool, bubbles: bool,
data: serde_value::Value, data: serde_json::Value,
} }
let Inner { let Inner {
@@ -35,18 +35,15 @@ impl<'de> Deserialize<'de> for HtmlEvent {
} = Inner::deserialize(deserializer)?; } = Inner::deserialize(deserializer)?;
// in debug mode let's try and be helpful as to why the deserialization failed // in debug mode let's try and be helpful as to why the deserialization failed
#[cfg(debug_assertions)] let data = deserialize_raw(&name, &data).map_err(|e| {
{ serde::de::Error::custom(format!(
_ = deserialize_raw(&name, data.clone()).unwrap_or_else(|e| { "Failed to deserialize event data for event {}: {:#?}\n'{:#?}'",
panic!( name, e, data,
"Failed to deserialize event data for event {}: {:#?}\n'{:#?}'", ))
name, e, data, })?;
)
});
}
Ok(HtmlEvent { Ok(HtmlEvent {
data: deserialize_raw(&name, data).unwrap(), data,
element, element,
bubbles, bubbles,
name, name,
@@ -55,15 +52,12 @@ impl<'de> Deserialize<'de> for HtmlEvent {
} }
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
fn deserialize_raw( fn deserialize_raw(name: &str, data: &serde_json::Value) -> Result<EventData, serde_json::Error> {
name: &str,
data: serde_value::Value,
) -> Result<EventData, serde_value::DeserializerError> {
use EventData::*; use EventData::*;
// a little macro-esque thing to make the code below more readable // a little macro-esque thing to make the code below more readable
#[inline] #[inline]
fn de<'de, F>(f: serde_value::Value) -> Result<F, serde_value::DeserializerError> fn de<'de, F>(f: &'de serde_json::Value) -> Result<F, serde_json::Error>
where where
F: Deserialize<'de>, F: Deserialize<'de>,
{ {
@@ -134,10 +128,9 @@ fn deserialize_raw(
// OtherData => "abort" | "afterprint" | "beforeprint" | "beforeunload" | "hashchange" | "languagechange" | "message" | "offline" | "online" | "pagehide" | "pageshow" | "popstate" | "rejectionhandled" | "storage" | "unhandledrejection" | "unload" | "userproximity" | "vrdisplayactivate" | "vrdisplayblur" | "vrdisplayconnect" | "vrdisplaydeactivate" | "vrdisplaydisconnect" | "vrdisplayfocus" | "vrdisplaypointerrestricted" | "vrdisplaypointerunrestricted" | "vrdisplaypresentchange"; // OtherData => "abort" | "afterprint" | "beforeprint" | "beforeunload" | "hashchange" | "languagechange" | "message" | "offline" | "online" | "pagehide" | "pageshow" | "popstate" | "rejectionhandled" | "storage" | "unhandledrejection" | "unload" | "userproximity" | "vrdisplayactivate" | "vrdisplayblur" | "vrdisplayconnect" | "vrdisplaydeactivate" | "vrdisplaydisconnect" | "vrdisplayfocus" | "vrdisplaypointerrestricted" | "vrdisplaypointerunrestricted" | "vrdisplaypresentchange";
other => { other => {
return Err(serde_value::DeserializerError::UnknownVariant( return Err(serde::de::Error::custom(format!(
other.to_string(), "Unknown event type: {other}"
&[], )))
))
} }
}; };