1 use std::io::{self, Write};
2 use std::panic::{self, AssertUnwindSafe};
3 use std::process;
4
catch_unwind<F, R>(label: &'static str, foreign_call: F) -> R where F: FnOnce() -> R,5 pub fn catch_unwind<F, R>(label: &'static str, foreign_call: F) -> R
6 where
7 F: FnOnce() -> R,
8 {
9 // Regarding the AssertUnwindSafe: we immediately abort on panic so it
10 // doesn't matter whether the types involved are unwind-safe. The UnwindSafe
11 // bound on catch_unwind is about ensuring nothing is in a broken state if
12 // your program plans to continue after the panic.
13 match panic::catch_unwind(AssertUnwindSafe(foreign_call)) {
14 Ok(ret) => ret,
15 Err(_) => abort(label),
16 }
17 }
18
19 #[cold]
abort(label: &'static str) -> !20 fn abort(label: &'static str) -> ! {
21 let mut stderr = io::stderr();
22 let _ = writeln!(stderr, "Error: panic in ffi function {}, aborting.", label);
23 process::abort();
24 }
25