Skip to content

Commit

Permalink
feat: add a panic handler to netpulse and netpulsed #13
Browse files Browse the repository at this point in the history
no human-panic because that has a shitton of deps
  • Loading branch information
PlexSheep committed Nov 12, 2024
1 parent 7d4db02 commit 43b70ff
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/bins/netpulse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
use getopts::Options;
use netpulse::analyze;
use netpulse::common::{init_logging, print_usage};
use netpulse::common::{init_logging, print_usage, setup_panic_handler};
use netpulse::errors::RunError;
use netpulse::records::{display_group, Check};
use netpulse::store::Store;
use tracing::error;

fn main() {
setup_panic_handler();
init_logging(tracing::Level::INFO);
let args: Vec<String> = std::env::args().collect();
let program = &args[0];
Expand Down
2 changes: 2 additions & 0 deletions src/bins/netpulsed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use daemonize::Daemonize;
use getopts::Options;
use netpulse::common::{
confirm, exec_cmd_for_user, getpid, getpid_running, init_logging, print_usage, root_guard,
setup_panic_handler,
};
use netpulse::errors::RunError;
use netpulse::store::Store;
Expand All @@ -53,6 +54,7 @@ const SYSTEMD_SERVICE_PATH: &str = "/etc/systemd/system/netpulsed.service";
static USES_DAEMON_SYSTEM: AtomicBool = AtomicBool::new(false);

fn main() -> Result<(), RunError> {
setup_panic_handler();
init_logging(tracing::Level::DEBUG);
let args: Vec<String> = std::env::args().collect();
let program = &args[0];
Expand Down
79 changes: 79 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,82 @@ pub fn fmt_timestamp(timestamp: impl Into<DateTime<Local>>) -> String {
let a: chrono::DateTime<chrono::Local> = timestamp.into();
format!("{}", a.format(TIME_FORMAT_HUMANS))
}

/// Sets up a custom panic handler for user-friendly error reporting.
///
/// Should be called early in the program startup, ideally before any other operations.
/// In debug builds, uses the default panic handler for detailed debugging output.
/// In release builds, provides a user-friendly error message with reporting instructions.
///
/// # Example Output
///
/// ```text
/// Well, this is embarrassing.
///
/// netpulse had a problem and crashed. This is a bug and should be reported!
///
/// Technical details:
/// Version: 0.1.0
/// OS: linux x86_64
/// Command: netpulse --check
/// Error: called `Option::unwrap()` on a `None` value
/// Location: src/store.rs:142
///
/// Please create a new issue at https://github.com/PlexSheep/netpulse/issues
/// with the above technical details and what you were doing when this happened.
/// ```
pub fn setup_panic_handler() {
if !cfg!(debug_assertions) {
// Only override in release builds
std::panic::set_hook(Box::new(|panic_info| {
let mut message = String::new();
message.push_str("\nWell, this is embarrassing.\n\n");
message.push_str(&format!(
"{} had a problem and crashed. This is a bug and should be reported!\n\n",
env!("CARGO_PKG_NAME")
));

message.push_str("Technical details:\n");
message.push_str(&format!("Version: {}\n", env!("CARGO_PKG_VERSION")));

// Get OS info
#[cfg(target_os = "linux")]
let os = "linux";
#[cfg(target_os = "macos")]
let os = "macos";
#[cfg(target_os = "windows")]
let os = "windows";

message.push_str(&format!("OS: {} {}\n", os, std::env::consts::ARCH));

// Get command line
let args: Vec<_> = std::env::args().collect();
message.push_str(&format!("Command: {}\n", args.join(" ")));

// Extract error message and location
if let Some(msg) = panic_info.payload().downcast_ref::<&str>() {
message.push_str(&format!("Error: {}\n", msg));
} else if let Some(msg) = panic_info.payload().downcast_ref::<String>() {
message.push_str(&format!("Error: {}\n", msg));
}

if let Some(location) = panic_info.location() {
message.push_str(&format!(
"Location: {}:{}\n",
location.file(),
location.line()
));
}

message.push_str(
"\nPlease create a new issue at https://github.com/PlexSheep/netpulse/issues\n",
);
message.push_str(
"with the above technical details and what you were doing when this happened.\n",
);

eprintln!("{}", message);
std::process::exit(1);
}));
}
}

0 comments on commit 43b70ff

Please sign in to comment.