maybe_unwind/hook.rs
1use crate::{
2 context::Context,
3 unwind::{Captured, Location},
4};
5use std::panic::PanicInfo;
6
7/// Capture the panic information.
8///
9/// The captured values are stored in the thread local context
10/// for passing to the caller of `maybe_unwind`. After capturing
11/// the panic information, this function returns `true`.
12///
13/// If the panic location is outside of the closure passed to
14/// `maybe_unwind`, this function does nothing and just return
15/// `false`.
16///
17/// # Example
18///
19/// ```
20/// use maybe_unwind::{maybe_unwind, capture_panic_info};
21/// use std::panic::{self, PanicInfo};
22///
23/// fn my_hook(info: &PanicInfo) {
24/// let captured = capture_panic_info(info);
25///
26/// if !captured {
27/// println!("{}", info);
28/// }
29/// }
30/// panic::set_hook(Box::new(my_hook));
31///
32/// let res = maybe_unwind(|| { panic!("oops"); });
33/// assert!(res.is_err());
34/// ```
35#[inline]
36pub fn capture_panic_info(info: &PanicInfo) -> bool {
37 if !Context::is_set() {
38 return false;
39 }
40
41 let backtrace = capture_backtrace!();
42
43 let _ = Context::try_with(|ctx| {
44 ctx.captured.replace(Captured {
45 location: info.location().map(|loc| Location::from_std(loc)),
46 backtrace,
47 });
48 });
49
50 true
51}