1 use std::any::Any; 2 use std::cell::RefCell; 3 4 thread_local!(static LAST_ERROR: RefCell<Option<Box<dyn Any + Send>>> = { 5 RefCell::new(None) 6 }); 7 wrap<T, F: FnOnce() -> T + std::panic::UnwindSafe>(f: F) -> Option<T>8pub fn wrap<T, F: FnOnce() -> T + std::panic::UnwindSafe>(f: F) -> Option<T> { 9 use std::panic; 10 if LAST_ERROR.with(|slot| slot.borrow().is_some()) { 11 return None; 12 } 13 match panic::catch_unwind(f) { 14 Ok(ret) => Some(ret), 15 Err(e) => { 16 LAST_ERROR.with(move |slot| { 17 *slot.borrow_mut() = Some(e); 18 }); 19 None 20 } 21 } 22 } 23 check()24pub fn check() { 25 let err = LAST_ERROR.with(|slot| slot.borrow_mut().take()); 26 if let Some(err) = err { 27 std::panic::resume_unwind(err); 28 } 29 } 30 panicked() -> bool31pub fn panicked() -> bool { 32 LAST_ERROR.with(|slot| slot.borrow().is_some()) 33 } 34