@@ -79,10 +79,42 @@ cfg_if! {
7979 extern {
8080 #[ wasm_bindgen( js_namespace = console) ]
8181 fn error( msg: String ) ;
82+
83+ type Error ;
84+
85+ #[ wasm_bindgen( constructor) ]
86+ fn new( ) -> Error ;
87+
88+ #[ wasm_bindgen( structural, method, getter) ]
89+ fn stack( error: & Error ) -> String ;
8290 }
8391
8492 fn hook_impl( info: & panic:: PanicInfo ) {
85- error( info. to_string( ) ) ;
93+ let mut msg = info. to_string( ) ;
94+
95+ // Add the error stack to our message.
96+ //
97+ // This ensures that even if the `console` implementation doesn't
98+ // include stacks for `console.error`, the stack is still available
99+ // for the user. Additionally, Firefox's console tries to clean up
100+ // stack traces, and ruins Rust symbols in the process
101+ // (https://bugzilla.mozilla.org/show_bug.cgi?id=1519569) but since
102+ // it only touches the logged message's associated stack, and not
103+ // the message's contents, by including the stack in the message
104+ // contents we make sure it is available to the user.
105+ msg. push_str( "\n \n Stack:\n \n " ) ;
106+ let e = Error :: new( ) ;
107+ let stack = e. stack( ) ;
108+ msg. push_str( & stack) ;
109+
110+ // Safari's devtools, on the other hand, _do_ mess with logged
111+ // messages' contents, so we attempt to break their heuristics for
112+ // doing that by appending some whitespace.
113+ // https://github.com/rustwasm/console_error_panic_hook/issues/7
114+ msg. push_str( "\n \n " ) ;
115+
116+ // Finally, log the panic with `console.error`!
117+ error( msg) ;
86118 }
87119 } else {
88120 use std:: io:: { self , Write } ;
0 commit comments