repose_core/
error.rs

1#![allow(non_snake_case)]
2use crate::View;
3use std::panic::{AssertUnwindSafe, catch_unwind};
4use std::rc::Rc;
5
6pub struct ErrorInfo {
7    pub message: String,
8    pub component: String,
9}
10
11pub fn ErrorBoundary(
12    fallback: impl Fn(ErrorInfo) -> View + 'static,
13    content: impl Fn() -> View + 'static,
14) -> View {
15    let fallback = Rc::new(fallback);
16    let content = Rc::new(content);
17
18    match catch_unwind(AssertUnwindSafe(|| content())) {
19        Ok(view) => view,
20        Err(err) => {
21            let message = if let Some(s) = err.downcast_ref::<String>() {
22                s.clone()
23            } else if let Some(s) = err.downcast_ref::<&str>() {
24                s.to_string()
25            } else {
26                "Unknown panic".to_string()
27            };
28
29            fallback(ErrorInfo {
30                message,
31                component: "Unknown".to_string(),
32            })
33        }
34    }
35}