From bd96237560f7d882b90e140194ef4bb269558603 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 5 Jan 2026 13:46:47 +0100 Subject: [PATCH 1/7] Fix clippy lints --- tests/test_hook.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_hook.rs b/tests/test_hook.rs index f8d7355..d6cdde7 100644 --- a/tests/test_hook.rs +++ b/tests/test_hook.rs @@ -40,7 +40,7 @@ fn test_original_hook() { }); let _ = panic::catch_unwind(|| panic!("Test")); - assert_eq!(*ran_hook.lock().unwrap(), true); + assert!(*ran_hook.lock().unwrap()); } #[test] @@ -60,7 +60,7 @@ fn test_no_original_hook() { }); let _ = panic::catch_unwind(|| panic!("Test")); - assert_eq!(*ran_hook.lock().unwrap(), false); + assert!(!*ran_hook.lock().unwrap()); } #[test] From cdc8b57b0f7aa706f6866c3498583f29e8b0bed7 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 5 Jan 2026 11:29:47 +0100 Subject: [PATCH 2/7] Include `String` type in panic `payload` casting We know from experience - [and the `payload()` docs] - that the returned payload can be a `&'static str` or `String`, but we only downcast the former meaning that any owned (typically because of being `Debug`-formatted) error messages are not included in the panic log. Add the cast to include them. Note that Rust 1.91, slightly more than 2 months old at the time of writing added this cast to the `PanicHookInfo` type directly: https://doc.rust-lang.org/stable/std/panic/struct.PanicHookInfo.html#method.payload_as_str [and the `payload()` docs]: https://doc.rust-lang.org/stable/std/panic/struct.PanicHookInfo.html#method.payload --- src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 2b84600..0daa717 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,7 +49,12 @@ pub fn initialize_hook(config: Configuration) { } else { "".to_owned() }; - let message = info.payload().downcast_ref::<&str>().unwrap_or(&""); + let message = info + .payload() + .downcast_ref::<&str>() + .copied() + .or_else(|| info.payload().downcast_ref::().map(|s| s.as_str())) + .unwrap_or(""); let backtrace = if config.force_capture { backtrace::Backtrace::force_capture() From 8f92462e295d6c5cb5d7070c3177afefbe7001b2 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 24 Apr 2025 16:16:21 +0200 Subject: [PATCH 3/7] cargo: Set `rust-version` to keep in sync with the CI MSRV Set the `rust-version` in `Cargo.toml` for a multitude of reasons (crates.io shows it to users, and `cargo` can use it in its MSRV-aware resolver), including the `+nightly -Zminimal-versions generate-lockfile` step to generate a compatible `version = 3` `Cargo.lock` for MSRV 1.74 to consume, rather than `version = 4` which it doesn't understand yet. --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index b35554b..dbc7706 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ description = "Log panics to the `log` macro as error" include = ["src", "LICENSE"] categories = ["development-tools", "development-tools::debugging"] # https://crates.io/category_slugs keywords = ["log", "panic"] +rust-version = "1.74" [dependencies] log = "0.4" From a6f50d8249992e67c5ea000544123d5f31c0eba9 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 5 Jan 2026 13:39:21 +0100 Subject: [PATCH 4/7] Bump `log` to `0.4.4` to fix `-Zminimal-versions` dependency Before that, the `log!` macro is not found inside `error!` expansion. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index dbc7706..7f7b4c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,4 @@ keywords = ["log", "panic"] rust-version = "1.74" [dependencies] -log = "0.4" +log = "0.4.4" From 4f4cb150fc50a50d7f24ba8018fc7b76d6d349f2 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 5 Jan 2026 13:42:30 +0100 Subject: [PATCH 5/7] README: Fix compilation of code-example Because the `README` is _intentionally_ included as the root module/library documentation, its code sample is susceptible to `cargo tests` doctests. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f6f05c4..32f7e43 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,6 @@ Call this somewhere at the start of your program (after initializing your logger ```rust use panic_log::Configuration; -[...] +// ... panic_log::initialize_hook(Configuration::default()); ``` From e3d42a9baec49fbcc4e57810044c040de3f53a4d Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 5 Jan 2026 13:50:23 +0100 Subject: [PATCH 6/7] tests: Serialize the tests to not cause spurious failures in concurrent panic hook overwrites --- tests/test_hook.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/test_hook.rs b/tests/test_hook.rs index d6cdde7..6a4de0d 100644 --- a/tests/test_hook.rs +++ b/tests/test_hook.rs @@ -6,25 +6,41 @@ use std::{ use panic_log::{initialize_hook, Configuration}; +// The test binary runs all tests in parallel by default; this lets multiple tests overwrite the +// panic hook concurrently and cause spurious failure. +static SERIAL_TEST: Mutex<()> = Mutex::new(()); + #[test] #[should_panic] fn test() { + let _serial = SERIAL_TEST.lock().unwrap(); + initialize_hook(Configuration::default()); + + // Drop the lock to not poison it + drop(_serial); panic!("Test"); } #[test] #[should_panic] fn test_forced_trace() { + let _serial = SERIAL_TEST.lock().unwrap(); + initialize_hook(Configuration { force_capture: true, ..Default::default() }); + + // Drop the lock to not poison it + drop(_serial); panic!("Test"); } #[test] fn test_original_hook() { + let _serial = SERIAL_TEST.lock().unwrap(); + let original_hook = panic::take_hook(); let ran_hook = Arc::new(Mutex::new(false)); let ran_hook_copy = Arc::clone(&ran_hook); @@ -45,6 +61,8 @@ fn test_original_hook() { #[test] fn test_no_original_hook() { + let _serial = SERIAL_TEST.lock().unwrap(); + let original_hook = panic::take_hook(); let ran_hook = Arc::new(Mutex::new(false)); let ran_hook_copy = Arc::clone(&ran_hook); @@ -65,6 +83,8 @@ fn test_no_original_hook() { #[test] fn test_flush_logger() { + let _serial = SERIAL_TEST.lock().unwrap(); + struct Logger { pub flushed: Arc>, } From 1fab6e953837216627ed0e476e3d7c1d84ec0f01 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 5 Jan 2026 13:53:14 +0100 Subject: [PATCH 7/7] CI: Skip tests in MSRV-1.74 check because of unstabilized `lazy_cell` feature --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7a543a..ad52328 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,4 +25,5 @@ jobs: run: cargo -Zminimal-versions generate-lockfile - uses: dtolnay/rust-toolchain@1.74.0 - name: Cargo check - run: cargo check --workspace --all-targets + # skip the tests, which require the lazy_cell feature from Rust 1.80 + run: cargo check --workspace