Skip to main content

hotshot_new_protocol/coordinator/
error.rs

1use std::fmt;
2
3use crate::{
4    block::BlockError, epoch::EpochManagerError, network::NetworkError, proposal::ValidationError,
5};
6
7#[derive(Debug, thiserror::Error)]
8#[error("{severity} coordinator error ({context}): source: {source}")]
9pub struct CoordinatorError {
10    pub severity: Severity,
11    pub source: ErrorSource,
12    pub context: &'static str,
13}
14
15impl CoordinatorError {
16    pub fn regular<E: Into<ErrorSource>>(e: E) -> Self {
17        Self {
18            context: "",
19            severity: Severity::Regular,
20            source: e.into(),
21        }
22    }
23
24    pub fn critical<E: Into<ErrorSource>>(e: E) -> Self {
25        Self {
26            context: "",
27            severity: Severity::Critical,
28            source: e.into(),
29        }
30    }
31
32    pub fn unspecified() -> Self {
33        Self {
34            context: "",
35            severity: Severity::Unspecified,
36            source: ErrorSource::Unspecified,
37        }
38    }
39
40    pub fn context(mut self, m: &'static str) -> Self {
41        self.context = m;
42        self
43    }
44}
45
46#[derive(Debug, Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
47pub enum Severity {
48    Unspecified,
49    Regular,
50    Critical,
51}
52
53impl fmt::Display for Severity {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        match self {
56            Self::Unspecified => f.write_str("unspecified"),
57            Self::Regular => f.write_str("regular"),
58            Self::Critical => f.write_str("critical"),
59        }
60    }
61}
62
63#[derive(Debug, thiserror::Error)]
64#[non_exhaustive]
65pub enum ErrorSource {
66    #[error("network error: {0}")]
67    Network(#[from] NetworkError),
68
69    #[error("proposal validation error: {0}")]
70    Proposal(#[from] ValidationError),
71
72    #[error("unspecified error")]
73    Unspecified,
74
75    #[error("coordinator has no inputs")]
76    NoInput,
77
78    #[error("{0}")]
79    StaticMessage(&'static str),
80
81    #[error("{0}")]
82    Message(String),
83
84    #[error("block builder error: {0}")]
85    Block(#[from] BlockError),
86
87    #[error("epoch manager error: {0}")]
88    EpochManager(#[from] EpochManagerError),
89}
90
91impl From<NetworkError> for CoordinatorError {
92    fn from(e: NetworkError) -> Self {
93        if e.is_critical() {
94            Self::critical(e)
95        } else {
96            Self::regular(e)
97        }
98    }
99}
100
101impl From<&'static str> for ErrorSource {
102    fn from(msg: &'static str) -> Self {
103        Self::StaticMessage(msg)
104    }
105}
106
107impl From<String> for ErrorSource {
108    fn from(msg: String) -> Self {
109        Self::Message(msg)
110    }
111}