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}