feat(panic_hook): implement custom panic hook for enhanced diagnostics on Leptos owner disposal
This commit is contained in:
parent
24c138b866
commit
46b6cf82e2
3 changed files with 63 additions and 2 deletions
|
@ -5,6 +5,7 @@ use tokio::sync::Mutex;
|
|||
use compareware::db::Database;
|
||||
use compareware::api::{ItemRequest, create_item, get_items, get_selected_properties, add_selected_property};
|
||||
use compareware::models::item::Item;
|
||||
use compareware::utils::panic_hook;
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
#[actix_web::main]
|
||||
|
@ -19,6 +20,8 @@ async fn main() -> std::io::Result<()> {
|
|||
use std::sync::Arc;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
panic_hook::init();
|
||||
|
||||
// Setup logging
|
||||
std::env::set_var("RUST_LOG", "info");
|
||||
|
||||
|
@ -167,12 +170,15 @@ pub fn main() {
|
|||
|
||||
#[cfg(all(not(feature = "ssr"), feature = "csr"))]
|
||||
pub fn main() {
|
||||
// Initialize custom panic hook for better diagnostics
|
||||
panic_hook::init();
|
||||
|
||||
// a client-side main function is required for using `trunk serve`
|
||||
// prefer using `cargo leptos serve` instead
|
||||
// to run: `trunk serve --open --features csr`
|
||||
use compareware::app::*;
|
||||
|
||||
console_error_panic_hook::set_once();
|
||||
// console_error_panic_hook::set_once();
|
||||
|
||||
leptos::mount_to_body(App);
|
||||
}
|
|
@ -1 +1,2 @@
|
|||
pub mod leptos_owner;
|
||||
pub mod panic_hook;
|
54
src/utils/panic_hook.rs
Normal file
54
src/utils/panic_hook.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
use std::panic;
|
||||
use leptos::logging::log;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
/// Sets up a custom panic hook that provides more context for Leptos owner disposal panics
|
||||
pub fn set_custom_panic_hook() {
|
||||
let original_hook = panic::take_hook();
|
||||
|
||||
panic::set_hook(Box::new(move |panic_info| {
|
||||
// Call the original hook first
|
||||
original_hook(panic_info);
|
||||
|
||||
// Extract panic message
|
||||
let message = if let Some(s) = panic_info.payload().downcast_ref::<String>() {
|
||||
s.clone()
|
||||
} else if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
|
||||
s.to_string()
|
||||
} else {
|
||||
"Unknown panic".to_string()
|
||||
};
|
||||
|
||||
// Check if this is an owner disposal panic
|
||||
if message.contains("OwnerDisposed") {
|
||||
log!("[PANIC] Leptos owner disposal detected. This usually happens when:");
|
||||
log!("[PANIC] 1. A component has been unmounted but JavaScript is still calling into Rust");
|
||||
log!("[PANIC] 2. An effect or signal update is running after the component is gone");
|
||||
log!("[PANIC] 3. A closure or callback is being called after cleanup");
|
||||
|
||||
// Log current component registry state
|
||||
let js_code = r#"
|
||||
if (window.typeaheadRegistry) {
|
||||
console.log('[PANIC] Current typeahead registry:',
|
||||
Object.keys(window.typeaheadRegistry).map(id => ({
|
||||
id,
|
||||
alive: window.typeaheadRegistry[id].alive,
|
||||
initialized: window.typeaheadRegistry[id].initialized
|
||||
}))
|
||||
);
|
||||
} else {
|
||||
console.log('[PANIC] No typeahead registry found');
|
||||
}
|
||||
"#;
|
||||
|
||||
let _ = js_sys::eval(js_code);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/// Call in main.rs or app initialization
|
||||
pub fn init() {
|
||||
log!("[PANIC_HOOK] Setting up custom panic hook");
|
||||
set_custom_panic_hook();
|
||||
log!("[PANIC_HOOK] Custom panic hook set up successfully");
|
||||
}
|
Loading…
Add table
Reference in a new issue