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