|
| 1 | +//! # `console_error_panic_hook` |
| 2 | +//! |
| 3 | +//! [](https://travis-ci.org/rustwasm/console_error_panic_hook) |
| 4 | +//! |
| 5 | +//! This crate lets you debug panics on `wasm32-unknown-unknown` by providing a |
| 6 | +//! panic hook that forwards panic messages to |
| 7 | +//! [`console.error`](https://developer.mozilla.org/en-US/docs/Web/API/Console/error). |
| 8 | +//! |
| 9 | +//! When an error is reported with `console.error`, browser devtools and node.js |
| 10 | +//! will typically capture a stack trace and display it with the logged error |
| 11 | +//! message. |
| 12 | +//! |
| 13 | +//! ## Usage |
| 14 | +//! |
| 15 | +//! There are two ways to install this panic hook. |
| 16 | +//! |
| 17 | +//! First, you can set the hook yourself by calling `std::panic::set_hook` in |
| 18 | +//! some initialization function: |
| 19 | +//! |
| 20 | +//! ``` |
| 21 | +//! extern crate console_error_panic_hook; |
| 22 | +//! use std::panic; |
| 23 | +//! |
| 24 | +//! fn my_init_function() { |
| 25 | +//! panic::set_hook(Box::new(console_error_panic_hook::hook)); |
| 26 | +//! |
| 27 | +//! // ... |
| 28 | +//! } |
| 29 | +//! ``` |
| 30 | +//! |
| 31 | +//! Alternatively, use `set_once` on some common code path to ensure that |
| 32 | +//! `set_hook` is called, but only the one time. Under the hood, this uses |
| 33 | +//! `std::sync::Once`. |
| 34 | +//! |
| 35 | +//! ``` |
| 36 | +//! extern crate console_error_panic_hook; |
| 37 | +//! |
| 38 | +//! struct MyBigThing; |
| 39 | +//! |
| 40 | +//! impl MyBigThing { |
| 41 | +//! pub fn new() -> MyBigThing { |
| 42 | +//! console_error_panic_hook::set_once(); |
| 43 | +//! |
| 44 | +//! MyBigThing |
| 45 | +//! } |
| 46 | +//! } |
| 47 | +//! ``` |
| 48 | +
|
| 49 | +#![feature(proc_macro, wasm_custom_section, wasm_import_module)] |
| 50 | + |
| 51 | +#[macro_use] |
| 52 | +extern crate cfg_if; |
| 53 | + |
| 54 | +use std::panic; |
| 55 | + |
| 56 | +cfg_if! { |
| 57 | + if #[cfg(target_arch = "wasm32")] { |
| 58 | + extern crate wasm_bindgen; |
| 59 | + use wasm_bindgen::prelude::*; |
| 60 | + |
| 61 | + #[wasm_bindgen] |
| 62 | + extern { |
| 63 | + #[wasm_bindgen(js_namespace = console)] |
| 64 | + fn error(msg: String); |
| 65 | + } |
| 66 | + |
| 67 | + fn hook_impl(info: &panic::PanicInfo) { |
| 68 | + error(info.to_string()); |
| 69 | + } |
| 70 | + } else { |
| 71 | + use std::io::{self, Write}; |
| 72 | + |
| 73 | + fn hook_impl(info: &panic::PanicInfo) { |
| 74 | + let _ = writeln!(io::stderr(), "{}", info); |
| 75 | + } |
| 76 | + } |
| 77 | +} |
| 78 | + |
| 79 | +/// A panic hook for use with |
| 80 | +/// [`std::panic::set_hook`](https://doc.rust-lang.org/nightly/std/panic/fn.set_hook.html) |
| 81 | +/// that logs panics into |
| 82 | +/// [`console.error`](https://developer.mozilla.org/en-US/docs/Web/API/Console/error). |
| 83 | +/// |
| 84 | +/// On non-wasm targets, prints the panic to `stderr`. |
| 85 | +pub fn hook(info: &panic::PanicInfo) { |
| 86 | + hook_impl(info); |
| 87 | +} |
| 88 | + |
| 89 | +/// Set the `console.error` panic hook the first time this is called. Subsequent |
| 90 | +/// invocations do nothing. |
| 91 | +pub fn set_once() { |
| 92 | + use std::sync::{ONCE_INIT, Once}; |
| 93 | + static SET_HOOK: Once = ONCE_INIT; |
| 94 | + SET_HOOK.call_once(|| { |
| 95 | + panic::set_hook(Box::new(hook)); |
| 96 | + }); |
| 97 | +} |
0 commit comments