diff --git a/Cargo.lock b/Cargo.lock index 1ca78641..21d3a09d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2908,6 +2908,7 @@ name = "radicle-node" version = "0.15.0" dependencies = [ "amplify", + "backtrace", "bloomy", "bytes", "chrono", diff --git a/crates/radicle-node/Cargo.toml b/crates/radicle-node/Cargo.toml index 8e6d4d82..c46cb08f 100644 --- a/crates/radicle-node/Cargo.toml +++ b/crates/radicle-node/Cargo.toml @@ -10,12 +10,13 @@ build = "build.rs" rust-version.workspace = true [features] -default = ["systemd", "structured-logger"] +default = ["backtrace", "systemd", "structured-logger"] systemd = ["dep:radicle-systemd"] test = ["radicle/test", "radicle-crypto/test", "radicle-crypto/cyphernet", "radicle-protocol/test", "qcheck", "snapbox"] [dependencies] amplify = { workspace = true } +backtrace = { version = "0.3.75", optional = true } bloomy = "1.2" bytes = { workspace = true } chrono = { workspace = true, features = ["clock"] } diff --git a/crates/radicle-node/src/main.rs b/crates/radicle-node/src/main.rs index efa0aacd..4fbcf360 100644 --- a/crates/radicle-node/src/main.rs +++ b/crates/radicle-node/src/main.rs @@ -300,15 +300,40 @@ fn initialize_logging(options: &LogOptions) -> Result<(), Box"); + + let msg = info + .payload() + .downcast_ref::<&'static str>() + .copied() + .or(info.payload().downcast_ref::().map(|s| s.as_str())) + .unwrap_or("Box"); + + match info.location() { + Some(location) => { + log::error!( + target: "panic", "thread '{thread}' panicked at '{msg}': {}:{}{backtrace}", + location.file(), + location.line(), + ); + } + None => log::error!( + target: "panic", "thread '{thread}' panicked at '{msg}'{backtrace}", + ), } + log::logger().flush(); +} + +fn main() { let options = parse_options().unwrap_or_else(|err| { // The lexopt errors read nicely with a comma. eprintln!("Failed to parse options, {err:#}"); @@ -320,6 +345,8 @@ fn main() { exit(3); }); + std::panic::set_hook(Box::new(panic_hook)); + if let Err(err) = execute(options) { log::error!(target: "node", "{err:#}"); exit(1);