show panics in the toast in wasm (#4582)
This commit is contained in:
1 parent
165447a647
commit
74163984be
7 files changed
+68
-12
No files matched your search
Generated
-1
@@ -5686,7 +5686,6 @@ dependencies = [
|
||||
name = "dioxus-logger"
|
||||
version = "0.7.0-rc.0"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"dioxus",
|
||||
"dioxus-cli-config",
|
||||
"tracing",
|
||||
|
||||
@@ -307,7 +307,6 @@ criterion = { version = "0.6" }
|
||||
cargo_metadata = "0.19.2"
|
||||
parking_lot = "0.12.4"
|
||||
tracing-wasm = "0.2.1"
|
||||
console_error_panic_hook = "0.1.7"
|
||||
base16 = "0.2.1"
|
||||
digest = "0.10.7"
|
||||
sha2 = "0.10.9"
|
||||
|
||||
@@ -22,7 +22,6 @@ default = []
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
tracing-wasm = { workspace = true }
|
||||
console_error_panic_hook = { workspace = true }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
tracing-subscriber = { workspace = true, features = ["fmt"] }
|
||||
|
||||
@@ -91,7 +91,6 @@ pub fn init(level: Level) -> Result<(), SetGlobalDefaultError> {
|
||||
let layer = tracing_wasm::WASMLayer::new(layer_config);
|
||||
let reg = Registry::default().with(layer);
|
||||
|
||||
console_error_panic_hook::set_once();
|
||||
set_global_default(reg)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ use wasm_bindgen::JsCast as _;
|
||||
/// ```
|
||||
pub struct Config {
|
||||
pub(crate) hydrate: bool,
|
||||
pub(crate) panic_hook: bool,
|
||||
pub(crate) root: ConfigRoot,
|
||||
#[cfg(feature = "document")]
|
||||
pub(crate) history: Option<Rc<dyn dioxus_history::History>>,
|
||||
@@ -96,6 +97,7 @@ impl Default for Config {
|
||||
root: ConfigRoot::RootName("main".to_string()),
|
||||
#[cfg(feature = "document")]
|
||||
history: None,
|
||||
panic_hook: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,12 @@
|
||||
//! This sets up a websocket connection to the devserver and handles messages from it.
|
||||
//! We also set up a little recursive timer that will attempt to reconnect if the connection is lost.
|
||||
|
||||
use std::fmt::Display;
|
||||
use std::time::Duration;
|
||||
|
||||
use dioxus_devtools::{DevserverMsg, HotReloadMsg};
|
||||
use futures_channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender};
|
||||
use js_sys::JsString;
|
||||
use std::fmt::Display;
|
||||
use std::time::Duration;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen::{closure::Closure, JsValue};
|
||||
use web_sys::{window, CloseEvent, MessageEvent, WebSocket};
|
||||
@@ -21,15 +21,23 @@ const POLL_INTERVAL_SCALE_FACTOR: i32 = 2;
|
||||
const TOAST_TIMEOUT: Duration = Duration::from_secs(5);
|
||||
const TOAST_TIMEOUT_LONG: Duration = Duration::from_secs(3600); // Duration::MAX is too long for JS.
|
||||
|
||||
pub(crate) fn init() -> UnboundedReceiver<HotReloadMsg> {
|
||||
pub(crate) fn init(config: &crate::Config) -> UnboundedReceiver<HotReloadMsg> {
|
||||
// Create the tx/rx pair that we'll use for the top-level future in the dioxus loop
|
||||
let (tx, rx) = unbounded();
|
||||
|
||||
// Wire up the websocket to the devserver
|
||||
make_ws(tx.clone(), POLL_INTERVAL_MIN, false);
|
||||
|
||||
// Set up the playground
|
||||
playground(tx);
|
||||
|
||||
// Set up the panic hook
|
||||
if config.panic_hook {
|
||||
std::panic::set_hook(Box::new(|info| {
|
||||
hook_impl(info);
|
||||
}));
|
||||
}
|
||||
|
||||
rx
|
||||
}
|
||||
|
||||
@@ -223,7 +231,7 @@ pub(crate) fn show_toast(
|
||||
_ = js_sys::eval(&format!(
|
||||
r#"
|
||||
if (typeof {js_fn_name} !== "undefined") {{
|
||||
window.{js_fn_name}("{header_text}", "{message}", "{level}", {as_ms});
|
||||
window.{js_fn_name}(`{header_text}`, `{message}`, `{level}`, {as_ms});
|
||||
}}
|
||||
"#,
|
||||
));
|
||||
@@ -289,3 +297,53 @@ fn playground(tx: UnboundedSender<HotReloadMsg>) {
|
||||
|
||||
binding.forget();
|
||||
}
|
||||
|
||||
fn hook_impl(info: &std::panic::PanicHookInfo) {
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
fn error(msg: String);
|
||||
|
||||
type Error;
|
||||
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new() -> Error;
|
||||
|
||||
#[wasm_bindgen(structural, method, getter)]
|
||||
fn stack(error: &Error) -> String;
|
||||
}
|
||||
|
||||
let mut msg = info.to_string();
|
||||
|
||||
// Add the error stack to our message.
|
||||
//
|
||||
// This ensures that even if the `console` implementation doesn't
|
||||
// include stacks for `console.error`, the stack is still available
|
||||
// for the user. Additionally, Firefox's console tries to clean up
|
||||
// stack traces, and ruins Rust symbols in the process
|
||||
// (https://bugzilla.mozilla.org/show_bug.cgi?id=1519569) but since
|
||||
// it only touches the logged message's associated stack, and not
|
||||
// the message's contents, by including the stack in the message
|
||||
// contents we make sure it is available to the user.
|
||||
msg.push_str("\n\nStack:\n\n");
|
||||
let e = Error::new();
|
||||
let stack = e.stack();
|
||||
msg.push_str(&stack);
|
||||
|
||||
// Safari's devtools, on the other hand, _do_ mess with logged
|
||||
// messages' contents, so we attempt to break their heuristics for
|
||||
// doing that by appending some whitespace.
|
||||
// https://github.com/rustwasm/console_error_panic_hook/issues/7
|
||||
msg.push_str("\n\n");
|
||||
|
||||
// Log the panic with `console.error`!
|
||||
error(msg.clone());
|
||||
|
||||
show_toast(
|
||||
"App panicked! See console for details.",
|
||||
&msg,
|
||||
ToastLevel::Error,
|
||||
TOAST_TIMEOUT_LONG,
|
||||
false,
|
||||
)
|
||||
}
|
||||
@@ -51,6 +51,9 @@ pub use hydration::*;
|
||||
/// wasm_bindgen_futures::spawn_local(app_fut);
|
||||
/// ```
|
||||
pub async fn run(mut virtual_dom: VirtualDom, web_config: Config) -> ! {
|
||||
#[cfg(all(feature = "devtools", debug_assertions))]
|
||||
let mut hotreload_rx = devtools::init(&web_config);
|
||||
|
||||
#[cfg(feature = "document")]
|
||||
if let Some(history) = web_config.history.clone() {
|
||||
virtual_dom.in_runtime(|| dioxus_core::ScopeId::ROOT.provide_context(history));
|
||||
@@ -61,9 +64,6 @@ pub async fn run(mut virtual_dom: VirtualDom, web_config: Config) -> ! {
|
||||
|
||||
let runtime = virtual_dom.runtime();
|
||||
|
||||
#[cfg(all(feature = "devtools", debug_assertions))]
|
||||
let mut hotreload_rx = devtools::init();
|
||||
|
||||
// If the hydrate feature is enabled, launch the client with hydration enabled
|
||||
let should_hydrate = web_config.hydrate || cfg!(feature = "hydrate");
|
||||
|
||||
|
||||
Reference in new issue
Block a user