zebra_chain/diagnostic/
task.rs

1//! Diagnostic types and functions for Zebra tasks:
2//! - OS thread handling
3//! - async future task handling
4//! - errors and panics
5
6#[cfg(feature = "async-error")]
7pub mod future;
8
9pub mod thread;
10
11/// A trait that checks a task's return value for panics.
12pub trait CheckForPanics: Sized {
13    /// The output type, after removing panics from `Self`.
14    type Output;
15
16    /// Check if `self` contains a panic payload or an unexpected termination, then panic.
17    /// Otherwise, return the non-panic part of `self`.
18    ///
19    /// # Panics
20    ///
21    /// If `self` contains a panic payload or an unexpected termination.
22    #[track_caller]
23    fn panic_if_task_has_finished(self) -> Self::Output {
24        self.check_for_panics_with(true)
25    }
26
27    /// Check if `self` contains a panic payload, then panic.
28    /// Otherwise, return the non-panic part of `self`.
29    ///
30    /// # Panics
31    ///
32    /// If `self` contains a panic payload.
33    #[track_caller]
34    fn panic_if_task_has_panicked(self) -> Self::Output {
35        self.check_for_panics_with(false)
36    }
37
38    /// Check if `self` contains a panic payload, then panic. Also panics if
39    /// `panic_on_unexpected_termination` is true, and `self` is an unexpected termination.
40    /// Otherwise, return the non-panic part of `self`.
41    ///
42    /// # Panics
43    ///
44    /// If `self` contains a panic payload, or if we're panicking on unexpected terminations.
45    #[track_caller]
46    fn check_for_panics_with(self, panic_on_unexpected_termination: bool) -> Self::Output;
47}
48
49/// A trait that waits for a task to finish, then handles panics and cancellations.
50pub trait WaitForPanics: Sized {
51    /// The underlying task output, after removing panics and unwrapping termination results.
52    type Output;
53
54    /// Waits for `self` to finish, then check if its output is:
55    /// - a panic payload: resume that panic,
56    /// - an unexpected termination: panic with that error,
57    /// - an expected termination: hang waiting for shutdown.
58    ///
59    /// Otherwise, returns the task return value of `self`.
60    ///
61    /// # Panics
62    ///
63    /// If `self` contains a panic payload or an unexpected termination.
64    ///
65    /// # Hangs
66    ///
67    /// If `self` contains an expected termination, and we're shutting down anyway.
68    #[track_caller]
69    fn wait_and_panic_on_unexpected_termination(self) -> Self::Output {
70        self.wait_for_panics_with(true)
71    }
72
73    /// Waits for `self` to finish, then check if its output is:
74    /// - a panic payload: resume that panic,
75    /// - a task termination: hang waiting for shutdown.
76    ///
77    /// Otherwise, returns the task return value of `self`.
78    ///
79    /// # Panics
80    ///
81    /// If `self` contains a panic payload.
82    ///
83    /// # Hangs
84    ///
85    /// If `self` contains a task termination.
86    #[track_caller]
87    fn wait_for_panics(self) -> Self::Output {
88        self.wait_for_panics_with(false)
89    }
90
91    /// Waits for `self` to finish, then check if its output is:
92    /// - a panic payload: resume that panic,
93    /// - an unexpected termination:
94    ///   - if `panic_on_unexpected_termination` is true, panic with that error,
95    ///   - otherwise, hang waiting for shutdown,
96    /// - an expected termination: hang waiting for shutdown.
97    ///
98    /// Otherwise, returns the task return value of `self`.
99    ///
100    /// # Panics
101    ///
102    /// If `self` contains a panic payload, or if we're panicking on unexpected terminations.
103    ///
104    /// # Hangs
105    ///
106    /// If `self` contains an expected or ignored termination, and we're shutting down anyway.
107    #[track_caller]
108    fn wait_for_panics_with(self, panic_on_unexpected_termination: bool) -> Self::Output;
109}