1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
pub mod wasi_http;
pub mod wasm_tools;
mod wit_printer;

pub mod time {
    pub trait ClockFn: Fn() -> DateTime<Utc> + Send + Sync + Clone {}

    impl<C: Fn() -> DateTime<Utc> + Send + Sync + Clone> ClockFn for C {}

    use chrono::DateTime;
    use chrono::Utc;

    cfg_if::cfg_if! {
        if #[cfg(all(test, madsim))] {
            #[must_use]
            pub fn now() -> DateTime<Utc> {
                if madsim::rand::random() {
                    madsim::time::advance(std::time::Duration::from_millis(madsim::rand::random()));
                }
                DateTime::from(madsim::time::TimeHandle::current().now_time())
            }
            #[must_use]
            pub fn now_tokio_instant() -> tokio::time::Instant {
                if madsim::rand::random() {
                    madsim::time::advance(std::time::Duration::from_millis(madsim::rand::random()));
                }
                madsim::time::Instant::now()
            }
        } else {
            #[must_use]
            pub fn now() -> DateTime<Utc> {
                Utc::now()
            }
            #[must_use]
            pub fn now_tokio_instant() -> tokio::time::Instant {
                tokio::time::Instant::now()
            }
        }
    }
}

pub fn tracing_panic_hook(panic_info: &std::panic::PanicInfo) {
    let payload = panic_info.payload();
    #[allow(clippy::manual_map)]
    let payload = if let Some(s) = payload.downcast_ref::<&str>() {
        Some(&**s)
    } else if let Some(s) = payload.downcast_ref::<String>() {
        Some(s.as_str())
    } else {
        None
    };
    let location = panic_info.location().map(ToString::to_string);
    let backtrace = std::backtrace::Backtrace::capture();
    if backtrace.status() == std::backtrace::BacktraceStatus::Captured {
        tracing::error!(
            panic.payload = payload,
            panic.location = location,
            "A panic occurred: {backtrace}"
        );
        if let Some(payload) = payload {
            eprintln!("A panic occurred: {payload}\n{backtrace}");
        } else {
            eprintln!("A panic occurred\n{backtrace}");
        }
    } else {
        tracing::error!(
            panic.payload = payload,
            panic.location = location,
            "A panic occurred",
        );
        if let Some(payload) = payload {
            eprintln!("A panic occurred: {payload}");
        } else {
            eprintln!("A panic occurred");
        }
    }
}