pretty_panic/
lib.rs

1/* ------------------------------------------ */
2/* lib.rs - pretty-panic library source code. */
3/* ------------------------------------------ */
4
5// Set crate attributes.
6#![deny(missing_docs)]
7
8//!
9//! # pretty-panic
10//!
11//! Provides a simple way to deliver prettier panic messages to the user.
12//! Wraps around [`std::panic::set_hook()`](https://doc.rust-lang.org/std/panic/fn.set_hook.html), allowing you to easily change
13//! the panic message for your release builds.
14//!
15//! ## Example
16//! ```rust
17//! use pretty_panic::pretty_panic;
18//!
19//! fn main() {
20//!     pretty_panic!();
21//!
22//!     panic!("A panic message.");
23//! }
24//! ```
25//! It's that simple! The `pretty_panic!()` macro can take a custom panic handler function as an argument.
26//! If one isn't passed, it simply uses the default.
27
28/// Sets the panic handler function to a function of your choosing.
29///
30/// **Example**:
31/// ```rust
32/// use pretty_panic::pretty_panic;
33/// use std::panic::PanicInfo;
34/// fn main() {
35///     pretty_panic!(my_panic);
36///
37///     panic!("a panic message")
38/// }
39///
40/// fn my_panic() {
41///     loop { /* who needs to actually do something when they panic? */ }
42/// }
43/// ```
44#[macro_export]
45macro_rules! pretty_panic {
46    () => {
47        use std::panic::{set_hook, PanicInfo};
48        fn default_handler(e: &PanicInfo) {
49            use std::thread;
50            let pkg_name: String = env!("CARGO_PKG_NAME").into();
51            let pkg_ver: String = env!("CARGO_PKG_VERSION").into();
52            let pkg_devs: String = env!("CARGO_PKG_AUTHORS").replace(":", ", ").into();
53            let pkg_home: String = env!("CARGO_PKG_HOMEPAGE").into();
54            let t = thread::current();
55            let t = match t.name() {
56                Some(name) => name,
57                None => "unknown",
58            };
59
60            eprintln!("Uh oh!\n");
61            eprintln!("The program experienced a fatal error, and has panicked. Recommend you contact one");
62            eprintln!("of the authors for assistance. See below for some additional information:\n");
63            eprintln!("(If you are going to submit a bug report, include the entirety of this message!)");
64            eprintln!("{} v{} ({}) - panic start", pkg_name, pkg_ver, pkg_home);
65            eprintln!("     panic from thread [{}]:\n         {}\n", t, e);
66            eprintln!("Submit bug report to the authors: {}", pkg_devs);
67            eprintln!("{} v{} ({}) - panic end", pkg_name, pkg_ver, pkg_home);
68        }
69        set_hook(Box::new(|e| { default_handler(e) }));
70    };
71
72    ($fname:ident) => {
73            use std::panic::{set_hook, PanicInfo};
74            set_hook(Box::new(|e| { $fname(e) }));
75    }
76}