unwind panics into error boundaries
This commit is contained in:
1 parent
34956cdb31
commit
2e7b8cb178
4 files changed
+69
-23
No files matched your search
Generated
+36
-21
@@ -2201,7 +2201,7 @@ version = "0.5.0-alpha.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"criterion 0.3.6",
|
"criterion 0.3.6",
|
||||||
"dioxus-config-macro",
|
"dioxus-config-macro",
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"dioxus-core-macro",
|
"dioxus-core-macro",
|
||||||
"dioxus-desktop",
|
"dioxus-desktop",
|
||||||
"dioxus-fullstack",
|
"dioxus-fullstack",
|
||||||
@@ -2268,7 +2268,7 @@ dependencies = [
|
|||||||
"dioxus-autofmt",
|
"dioxus-autofmt",
|
||||||
"dioxus-check",
|
"dioxus-check",
|
||||||
"dioxus-cli-config",
|
"dioxus-cli-config",
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"dioxus-hot-reload",
|
"dioxus-hot-reload",
|
||||||
"dioxus-html",
|
"dioxus-html",
|
||||||
"dioxus-rsx",
|
"dioxus-rsx",
|
||||||
@@ -2357,6 +2357,20 @@ dependencies = [
|
|||||||
"tracing-subscriber",
|
"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]]
|
[[package]]
|
||||||
name = "dioxus-core-macro"
|
name = "dioxus-core-macro"
|
||||||
version = "0.5.0-alpha.0"
|
version = "0.5.0-alpha.0"
|
||||||
@@ -2387,7 +2401,7 @@ dependencies = [
|
|||||||
"core-foundation",
|
"core-foundation",
|
||||||
"dioxus",
|
"dioxus",
|
||||||
"dioxus-cli-config",
|
"dioxus-cli-config",
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"dioxus-hooks",
|
"dioxus-hooks",
|
||||||
"dioxus-hot-reload",
|
"dioxus-hot-reload",
|
||||||
"dioxus-html",
|
"dioxus-html",
|
||||||
@@ -2488,7 +2502,7 @@ name = "dioxus-hooks"
|
|||||||
version = "0.5.0-alpha.0"
|
version = "0.5.0-alpha.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dioxus",
|
"dioxus",
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"dioxus-debug-cell",
|
"dioxus-debug-cell",
|
||||||
"dioxus-signals",
|
"dioxus-signals",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
@@ -2506,7 +2520,7 @@ name = "dioxus-hot-reload"
|
|||||||
version = "0.5.0-alpha.0"
|
version = "0.5.0-alpha.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"dioxus-html",
|
"dioxus-html",
|
||||||
"dioxus-rsx",
|
"dioxus-rsx",
|
||||||
"execute",
|
"execute",
|
||||||
@@ -2523,7 +2537,7 @@ name = "dioxus-html"
|
|||||||
version = "0.5.0-alpha.0"
|
version = "0.5.0-alpha.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"dioxus-html-internal-macro",
|
"dioxus-html-internal-macro",
|
||||||
"dioxus-rsx",
|
"dioxus-rsx",
|
||||||
"enumset",
|
"enumset",
|
||||||
@@ -2556,7 +2570,7 @@ dependencies = [
|
|||||||
name = "dioxus-interpreter-js"
|
name = "dioxus-interpreter-js"
|
||||||
version = "0.5.0-alpha.0"
|
version = "0.5.0-alpha.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"dioxus-html",
|
"dioxus-html",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"md5",
|
"md5",
|
||||||
@@ -2572,7 +2586,7 @@ name = "dioxus-lib"
|
|||||||
version = "0.5.0-alpha.0"
|
version = "0.5.0-alpha.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dioxus-config-macro",
|
"dioxus-config-macro",
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"dioxus-core-macro",
|
"dioxus-core-macro",
|
||||||
"dioxus-hooks",
|
"dioxus-hooks",
|
||||||
"dioxus-html",
|
"dioxus-html",
|
||||||
@@ -2587,7 +2601,7 @@ dependencies = [
|
|||||||
"axum",
|
"axum",
|
||||||
"dioxus",
|
"dioxus",
|
||||||
"dioxus-cli-config",
|
"dioxus-cli-config",
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"dioxus-hot-reload",
|
"dioxus-hot-reload",
|
||||||
"dioxus-html",
|
"dioxus-html",
|
||||||
"dioxus-interpreter-js",
|
"dioxus-interpreter-js",
|
||||||
@@ -2621,7 +2635,7 @@ dependencies = [
|
|||||||
"anymap 1.0.0-beta.2",
|
"anymap 1.0.0-beta.2",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
"dioxus",
|
"dioxus",
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"dioxus-native-core",
|
"dioxus-native-core",
|
||||||
"dioxus-native-core-macro",
|
"dioxus-native-core-macro",
|
||||||
"keyboard-types",
|
"keyboard-types",
|
||||||
@@ -2730,7 +2744,7 @@ dependencies = [
|
|||||||
name = "dioxus-rsx"
|
name = "dioxus-rsx"
|
||||||
version = "0.5.0-alpha.0"
|
version = "0.5.0-alpha.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"internment",
|
"internment",
|
||||||
"krates",
|
"krates",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -2745,7 +2759,7 @@ name = "dioxus-signals"
|
|||||||
version = "0.5.0-alpha.0"
|
version = "0.5.0-alpha.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dioxus",
|
"dioxus",
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"generational-box",
|
"generational-box",
|
||||||
@@ -2769,7 +2783,7 @@ dependencies = [
|
|||||||
"async-trait",
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
"dioxus",
|
"dioxus",
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"dioxus-html",
|
"dioxus-html",
|
||||||
"dioxus-signals",
|
"dioxus-signals",
|
||||||
"fern",
|
"fern",
|
||||||
@@ -2800,7 +2814,7 @@ dependencies = [
|
|||||||
"criterion 0.3.6",
|
"criterion 0.3.6",
|
||||||
"crossterm 0.26.1",
|
"crossterm 0.26.1",
|
||||||
"dioxus",
|
"dioxus",
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"dioxus-hot-reload",
|
"dioxus-hot-reload",
|
||||||
"dioxus-html",
|
"dioxus-html",
|
||||||
"dioxus-native-core",
|
"dioxus-native-core",
|
||||||
@@ -2818,7 +2832,7 @@ dependencies = [
|
|||||||
"async-trait",
|
"async-trait",
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
"dioxus",
|
"dioxus",
|
||||||
"dioxus-core",
|
"dioxus-core 0.5.0-alpha.0",
|
||||||
"dioxus-html",
|
"dioxus-html",
|
||||||
"dioxus-interpreter-js",
|
"dioxus-interpreter-js",
|
||||||
"dioxus-ssr",
|
"dioxus-ssr",
|
||||||
@@ -5701,10 +5715,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "manganis"
|
name = "manganis"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c10916db4ed51967d92545eb5629ce1e1cc05c74da2cd2aab6ab6c57c2e838b6"
|
checksum = "a42db80aa639f70d6bf1d2ef93612d2ffbb33f6ea17d473b91bfeb3f67bc24bc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"dioxus-core 0.5.0-alpha.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"manganis-macro",
|
"manganis-macro",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -5737,9 +5752,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "manganis-common"
|
name = "manganis-common"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "82ee0f9002a9f5d7e3b662e55562996c60401bae16da23f3790c52e0823216ea"
|
checksum = "176dfb4bb5592b0d130176add9893af527ab565fc1bcf58ece88acd6276688d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
@@ -5753,9 +5768,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "manganis-macro"
|
name = "manganis-macro"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da50cc6074480dc6c255a09c9d48dd4a379e6162feb5d308ec33d5ba9da4e579"
|
checksum = "ab2c2e11190c2f3d6133cffda5c955b463a7e90b7ba866e71e7dfa65fa97ddfc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"manganis-common",
|
"manganis-common",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|||||||
@@ -20,6 +20,14 @@ fn app() -> Element {
|
|||||||
},
|
},
|
||||||
DemoC { x: 1 }
|
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")
|
||||||
|
}
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
use crate::{nodes::RenderReturn, ComponentFunction};
|
use crate::{
|
||||||
|
innerlude::{throw_error, CapturedPanic},
|
||||||
|
nodes::RenderReturn,
|
||||||
|
ComponentFunction,
|
||||||
|
};
|
||||||
use std::{any::Any, panic::AssertUnwindSafe};
|
use std::{any::Any, panic::AssertUnwindSafe};
|
||||||
|
|
||||||
pub(crate) type BoxedAnyProps = Box<dyn AnyProps>;
|
pub(crate) type BoxedAnyProps = Box<dyn AnyProps>;
|
||||||
@@ -79,6 +83,7 @@ impl<F: ComponentFunction<P, M> + Clone, P: Clone + 'static, M: 'static> AnyProp
|
|||||||
Err(err) => {
|
Err(err) => {
|
||||||
let component_name = self.name;
|
let component_name = self.name;
|
||||||
tracing::error!("Error while rendering component `{component_name}`: {err:?}");
|
tracing::error!("Error while rendering component `{component_name}`: {err:?}");
|
||||||
|
throw_error::<()>(CapturedPanic { error: err });
|
||||||
RenderReturn::default()
|
RenderReturn::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,20 @@ use std::{
|
|||||||
rc::Rc,
|
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<dyn Any + 'static>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
/// Provide an error boundary to catch errors from child components
|
||||||
pub fn use_error_boundary() -> ErrorBoundary {
|
pub fn use_error_boundary() -> ErrorBoundary {
|
||||||
use_hook(|| provide_context(ErrorBoundary::new()))
|
use_hook(|| provide_context(ErrorBoundary::new()))
|
||||||
@@ -201,7 +215,7 @@ pub trait Throw<S = ()>: Sized {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn throw_error<T>(e: impl Debug + 'static) -> Option<T> {
|
pub(crate) fn throw_error<T>(e: impl Debug + 'static) -> Option<T> {
|
||||||
if let Some(cx) = try_consume_context::<ErrorBoundary>() {
|
if let Some(cx) = try_consume_context::<ErrorBoundary>() {
|
||||||
match current_scope_id() {
|
match current_scope_id() {
|
||||||
Some(id) => cx.insert_error(id, Box::new(e), Backtrace::capture()),
|
Some(id) => cx.insert_error(id, Box::new(e), Backtrace::capture()),
|
||||||
|
|||||||
Reference in new issue
Block a user