Skip to main content

scion_sdk_utils/
panic_hook.rs

1// Copyright 2026 Anapaya Systems
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//   http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Copyright 2026 Anapaya Systems
16//! Panic hook that logs full panic details via the tracing framework.
17
18/// Installs a panic hook that logs the full panic location and message via
19/// [`tracing::error!`].
20///
21/// The previous hook is preserved and called after logging, so the default
22/// Rust behaviour (print to stderr, optionally abort) is retained.
23pub fn install_panic_hook() {
24    let prev = std::panic::take_hook();
25    std::panic::set_hook(Box::new(move |info| {
26        log_panic(info);
27        prev(info);
28    }));
29}
30
31fn log_panic(info: &std::panic::PanicHookInfo<'_>) {
32    let location = info
33        .location()
34        .map(|l| format!("{}:{}:{}", l.file(), l.line(), l.column()));
35    let location = location.as_deref().unwrap_or("<unknown location>");
36
37    let payload = info.payload();
38    let msg = if let Some(s) = payload.downcast_ref::<&str>() {
39        *s
40    } else if let Some(s) = payload.downcast_ref::<String>() {
41        s.as_str()
42    } else {
43        "<non-string panic payload>"
44    };
45
46    tracing::error!(location, message = msg, "Unexpected panic occurred");
47}