iota_common/
logging.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use once_cell::sync::Lazy;
6
7use crate::in_test_configuration;
8
9#[macro_export]
10macro_rules! fatal {
11    ($($arg:tt)*) => {{
12        tracing::error!(fatal = true, $($arg)*);
13        panic!($($arg)*);
14    }};
15}
16
17#[inline(always)]
18pub fn crash_on_debug() -> bool {
19    static CRASH_ON_DEBUG: Lazy<bool> = Lazy::new(|| {
20        in_test_configuration() || std::env::var("IOTA_ENABLE_DEBUG_ASSERTIONS").is_ok()
21    });
22
23    *CRASH_ON_DEBUG
24}
25
26#[macro_export]
27macro_rules! debug_fatal {
28    ($($arg:tt)*) => {{
29        if $crate::logging::crash_on_debug() {
30            $crate::fatal!($($arg)*);
31        } else {
32            let stacktrace = std::backtrace::Backtrace::capture();
33            tracing::error!(debug_fatal = true, stacktrace = ?stacktrace, $($arg)*);
34            let location = concat!(file!(), ':', line!());
35            if let Some(metrics) = iota_metrics::get_metrics() {
36                metrics.system_invariant_violations.with_label_values(&[location]).inc();
37            }
38        }
39    }};
40}
41
42mod tests {
43    #[test]
44    #[should_panic]
45    fn test_fatal() {
46        fatal!("This is a fatal error");
47    }
48
49    #[test]
50    #[should_panic]
51    fn test_debug_fatal() {
52        if cfg!(debug_assertions) {
53            debug_fatal!("This is a debug fatal error");
54        } else {
55            // pass in release mode as well
56            fatal!("This is a fatal error");
57        }
58    }
59
60    #[cfg(not(debug_assertions))]
61    #[test]
62    fn test_debug_fatal_release_mode() {
63        debug_fatal!("This is a debug fatal error");
64    }
65}