|
1 | 1 | //! A micro-crate to enhance panic messages with context info.
|
2 |
| -//! |
3 |
| -//! FIXME: upstream to <https://github.com/kriomant/panic-context> ? |
4 | 2 |
|
5 | 3 | use std::{cell::RefCell, panic, sync::Once};
|
6 | 4 |
|
7 |
| -pub fn enter(context: String) -> PanicContext { |
8 |
| - static ONCE: Once = Once::new(); |
9 |
| - ONCE.call_once(PanicContext::init); |
10 |
| - |
11 |
| - with_ctx(|ctx| ctx.push(context)); |
12 |
| - PanicContext { _priv: () } |
13 |
| -} |
14 |
| - |
| 5 | +/// Dummy for leveraging RAII cleanup to pop frames. |
15 | 6 | #[must_use]
|
16 | 7 | pub struct PanicContext {
|
| 8 | + // prevent arbitrary construction |
17 | 9 | _priv: (),
|
18 | 10 | }
|
19 | 11 |
|
20 |
| -impl PanicContext { |
| 12 | +impl Drop for PanicContext { |
| 13 | + fn drop(&mut self) { |
| 14 | + with_ctx(|ctx| assert!(ctx.pop().is_some())); |
| 15 | + } |
| 16 | +} |
| 17 | + |
| 18 | +pub fn enter(frame: String) -> PanicContext { |
21 | 19 | #[allow(clippy::print_stderr)]
|
22 |
| - fn init() { |
| 20 | + fn set_hook() { |
23 | 21 | let default_hook = panic::take_hook();
|
24 |
| - #[allow(deprecated)] |
25 |
| - let hook = move |panic_info: &panic::PanicInfo<'_>| { |
| 22 | + panic::set_hook(Box::new(move |panic_info| { |
26 | 23 | with_ctx(|ctx| {
|
27 | 24 | if !ctx.is_empty() {
|
28 | 25 | eprintln!("Panic context:");
|
29 | 26 | for frame in ctx.iter() {
|
30 | 27 | eprintln!("> {frame}\n");
|
31 | 28 | }
|
32 | 29 | }
|
33 |
| - default_hook(panic_info); |
34 | 30 | });
|
35 |
| - }; |
36 |
| - panic::set_hook(Box::new(hook)); |
| 31 | + default_hook(panic_info); |
| 32 | + })); |
37 | 33 | }
|
38 |
| -} |
39 | 34 |
|
40 |
| -impl Drop for PanicContext { |
41 |
| - fn drop(&mut self) { |
42 |
| - with_ctx(|ctx| assert!(ctx.pop().is_some())); |
43 |
| - } |
| 35 | + static SET_HOOK: Once = Once::new(); |
| 36 | + SET_HOOK.call_once(set_hook); |
| 37 | + |
| 38 | + with_ctx(|ctx| ctx.push(frame)); |
| 39 | + PanicContext { _priv: () } |
44 | 40 | }
|
45 | 41 |
|
46 | 42 | fn with_ctx(f: impl FnOnce(&mut Vec<String>)) {
|
|
0 commit comments