From 2e7b8cb178959805358e3cdfe4f5be6616a32d6e Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 13 Mar 2024 18:55:57 -0500 Subject: [PATCH 1/3] unwind panics into error boundaries --- Cargo.lock | 57 ++++++++++++++++++----------- examples/error_handle.rs | 12 ++++++ packages/core/src/any_props.rs | 7 +++- packages/core/src/error_boundary.rs | 16 +++++++- 4 files changed, 69 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f59bd8cfd..1f6344ee9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2201,7 +2201,7 @@ version = "0.5.0-alpha.0" dependencies = [ "criterion 0.3.6", "dioxus-config-macro", - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "dioxus-core-macro", "dioxus-desktop", "dioxus-fullstack", @@ -2268,7 +2268,7 @@ dependencies = [ "dioxus-autofmt", "dioxus-check", "dioxus-cli-config", - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "dioxus-hot-reload", "dioxus-html", "dioxus-rsx", @@ -2357,6 +2357,20 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "dioxus-core" +version = "0.5.0-alpha.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f39bef0484998f724622964f04468ddfde7fd550f5f0f1aef9394306e9caba44" +dependencies = [ + "futures-channel", + "futures-util", + "longest-increasing-subsequence", + "rustc-hash", + "slab", + "tracing", +] + [[package]] name = "dioxus-core-macro" version = "0.5.0-alpha.0" @@ -2387,7 +2401,7 @@ dependencies = [ "core-foundation", "dioxus", "dioxus-cli-config", - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "dioxus-hooks", "dioxus-hot-reload", "dioxus-html", @@ -2488,7 +2502,7 @@ name = "dioxus-hooks" version = "0.5.0-alpha.0" dependencies = [ "dioxus", - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "dioxus-debug-cell", "dioxus-signals", "futures-channel", @@ -2506,7 +2520,7 @@ name = "dioxus-hot-reload" version = "0.5.0-alpha.0" dependencies = [ "chrono", - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "dioxus-html", "dioxus-rsx", "execute", @@ -2523,7 +2537,7 @@ name = "dioxus-html" version = "0.5.0-alpha.0" dependencies = [ "async-trait", - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "dioxus-html-internal-macro", "dioxus-rsx", "enumset", @@ -2556,7 +2570,7 @@ dependencies = [ name = "dioxus-interpreter-js" version = "0.5.0-alpha.0" dependencies = [ - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "dioxus-html", "js-sys", "md5", @@ -2572,7 +2586,7 @@ name = "dioxus-lib" version = "0.5.0-alpha.0" dependencies = [ "dioxus-config-macro", - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "dioxus-core-macro", "dioxus-hooks", "dioxus-html", @@ -2587,7 +2601,7 @@ dependencies = [ "axum", "dioxus", "dioxus-cli-config", - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "dioxus-hot-reload", "dioxus-html", "dioxus-interpreter-js", @@ -2621,7 +2635,7 @@ dependencies = [ "anymap 1.0.0-beta.2", "dashmap", "dioxus", - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "dioxus-native-core", "dioxus-native-core-macro", "keyboard-types", @@ -2730,7 +2744,7 @@ dependencies = [ name = "dioxus-rsx" version = "0.5.0-alpha.0" dependencies = [ - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "internment", "krates", "proc-macro2", @@ -2745,7 +2759,7 @@ name = "dioxus-signals" version = "0.5.0-alpha.0" dependencies = [ "dioxus", - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "futures-channel", "futures-util", "generational-box", @@ -2769,7 +2783,7 @@ dependencies = [ "async-trait", "chrono", "dioxus", - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "dioxus-html", "dioxus-signals", "fern", @@ -2800,7 +2814,7 @@ dependencies = [ "criterion 0.3.6", "crossterm 0.26.1", "dioxus", - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "dioxus-hot-reload", "dioxus-html", "dioxus-native-core", @@ -2818,7 +2832,7 @@ dependencies = [ "async-trait", "console_error_panic_hook", "dioxus", - "dioxus-core", + "dioxus-core 0.5.0-alpha.0", "dioxus-html", "dioxus-interpreter-js", "dioxus-ssr", @@ -5701,10 +5715,11 @@ dependencies = [ [[package]] name = "manganis" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c10916db4ed51967d92545eb5629ce1e1cc05c74da2cd2aab6ab6c57c2e838b6" +checksum = "a42db80aa639f70d6bf1d2ef93612d2ffbb33f6ea17d473b91bfeb3f67bc24bc" dependencies = [ + "dioxus-core 0.5.0-alpha.0 (registry+https://github.com/rust-lang/crates.io-index)", "manganis-macro", ] @@ -5737,9 +5752,9 @@ dependencies = [ [[package]] name = "manganis-common" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82ee0f9002a9f5d7e3b662e55562996c60401bae16da23f3790c52e0823216ea" +checksum = "176dfb4bb5592b0d130176add9893af527ab565fc1bcf58ece88acd6276688d1" dependencies = [ "anyhow", "base64", @@ -5753,9 +5768,9 @@ dependencies = [ [[package]] name = "manganis-macro" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da50cc6074480dc6c255a09c9d48dd4a379e6162feb5d308ec33d5ba9da4e579" +checksum = "ab2c2e11190c2f3d6133cffda5c955b463a7e90b7ba866e71e7dfa65fa97ddfc" dependencies = [ "manganis-common", "proc-macro2", diff --git a/examples/error_handle.rs b/examples/error_handle.rs index ccafe0642..04f6c3761 100644 --- a/examples/error_handle.rs +++ b/examples/error_handle.rs @@ -20,6 +20,14 @@ fn app() -> Element { }, DemoC { x: 1 } } + + ErrorBoundary { + handle_error: |error: CapturedError| rsx! { + h1 { "Another error occurred" } + pre { "{error:#?}" } + }, + ComponentPanic {} + } } } @@ -40,3 +48,7 @@ fn DemoC(x: i32) -> Element { } } } + +fn ComponentPanic() -> Element { + panic!("This component panics") +} diff --git a/packages/core/src/any_props.rs b/packages/core/src/any_props.rs index b737a549a..760b821dc 100644 --- a/packages/core/src/any_props.rs +++ b/packages/core/src/any_props.rs @@ -1,4 +1,8 @@ -use crate::{nodes::RenderReturn, ComponentFunction}; +use crate::{ + innerlude::{throw_error, CapturedPanic}, + nodes::RenderReturn, + ComponentFunction, +}; use std::{any::Any, panic::AssertUnwindSafe}; pub(crate) type BoxedAnyProps = Box; @@ -79,6 +83,7 @@ impl + Clone, P: Clone + 'static, M: 'static> AnyProp Err(err) => { let component_name = self.name; tracing::error!("Error while rendering component `{component_name}`: {err:?}"); + throw_error::<()>(CapturedPanic { error: err }); RenderReturn::default() } } diff --git a/packages/core/src/error_boundary.rs b/packages/core/src/error_boundary.rs index 6e1055c6e..88359dd1c 100644 --- a/packages/core/src/error_boundary.rs +++ b/packages/core/src/error_boundary.rs @@ -13,6 +13,20 @@ use std::{ rc::Rc, }; +/// A panic in a component that was caught by an error boundary. +/// +/// NOTE: WASM currently does not support caching unwinds, so this struct will not be created in WASM. +pub struct CapturedPanic { + /// The error that was caught + pub error: Box, +} + +impl Debug for CapturedPanic { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("CapturedPanic").finish() + } +} + /// Provide an error boundary to catch errors from child components pub fn use_error_boundary() -> ErrorBoundary { use_hook(|| provide_context(ErrorBoundary::new())) @@ -201,7 +215,7 @@ pub trait Throw: Sized { } } -fn throw_error(e: impl Debug + 'static) -> Option { +pub(crate) fn throw_error(e: impl Debug + 'static) -> Option { if let Some(cx) = try_consume_context::() { match current_scope_id() { Some(id) => cx.insert_error(id, Box::new(e), Backtrace::capture()), From 25844ae9d362c260ba646da8fa796bf2530166e5 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Fri, 15 Mar 2024 00:07:33 -0700 Subject: [PATCH 2/3] Fix: make clippy happy, don't set asset dir env --- packages/cli/src/builder.rs | 6 ------ packages/hot-reload/src/file_watcher.rs | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/cli/src/builder.rs b/packages/cli/src/builder.rs index 9a2c0ebb5..638572fda 100644 --- a/packages/cli/src/builder.rs +++ b/packages/cli/src/builder.rs @@ -335,12 +335,6 @@ pub fn build_desktop( let _manganis_support = ManganisSupportGuard::default(); let _guard = AssetConfigDropGuard::new(); - // set the asset dir via cli args - env::set_var( - "DIOXUS_ASSET_DIR", - config.asset_dir().canonicalize().unwrap(), - ); - let mut cmd = subprocess::Exec::cmd("cargo") .set_rust_flags(rust_flags) .env("CARGO_TARGET_DIR", &config.target_dir) diff --git a/packages/hot-reload/src/file_watcher.rs b/packages/hot-reload/src/file_watcher.rs index 04f5e4369..ce4a7c8d8 100644 --- a/packages/hot-reload/src/file_watcher.rs +++ b/packages/hot-reload/src/file_watcher.rs @@ -243,7 +243,7 @@ pub fn init(cfg: Config) { // FIXME: use a more robust system here for embedded discovery // // https://github.com/DioxusLabs/dioxus/issues/1914 - if listening_paths == &[""] { + if listening_paths == [""] { for entry in std::fs::read_dir(&crate_dir) .expect("failed to read rust crate directory. Are you running with cargo?") { From fe2c17f7922eccba1a3de1528c703e564270468c Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Fri, 15 Mar 2024 12:20:16 -0700 Subject: [PATCH 3/3] Make Clippy happy --- examples/error_handle.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/error_handle.rs b/examples/error_handle.rs index 04f6c3761..5c3279940 100644 --- a/examples/error_handle.rs +++ b/examples/error_handle.rs @@ -49,6 +49,7 @@ fn DemoC(x: i32) -> Element { } } +#[component] fn ComponentPanic() -> Element { panic!("This component panics") }