Skip to main content

urma_node/
error.rs

1#[derive(Debug)]
2pub enum Error {
3    Io(std::io::Error),
4    Database(rusqlite::Error),
5    Json(serde_json::Error),
6    Source(Box<dyn std::error::Error + Send + Sync>),
7    CommitSource(String),
8    Invalid(String),
9    Busy(String),
10    /// A remote peer answered Busy: its capacity, not ours.
11    PeerBusy,
12    /// A peer request failed in transport (dial, timeout, closed connection,
13    /// I/O, unsupported protocol): no statement about the peer's honesty.
14    Transport(String),
15    /// Our own connection admission refused a dial, before reaching the peer.
16    DialDenied(DialLimit),
17    Stale,
18}
19
20/// Which local admission limit refused a connection.
21#[derive(Clone, Copy, Debug, PartialEq, Eq)]
22pub enum DialLimit {
23    /// Too many connections still handshaking in that direction.
24    Pending,
25    /// Every established slot in that direction (or in total) is taken.
26    Established,
27    /// The peer already holds an established connection.
28    Duplicate,
29}
30
31impl std::fmt::Display for DialLimit {
32    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33        f.write_str(match self {
34            Self::Pending => "pending connection limit",
35            Self::Established => "established connection limit",
36            Self::Duplicate => "peer already connected",
37        })
38    }
39}
40
41impl std::fmt::Display for Error {
42    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43        match self {
44            Self::Io(e) => write!(f, "archive I/O: {e}"),
45            Self::Database(e) => write!(f, "archive database: {e}"),
46            Self::Json(e) => write!(f, "archive encoding: {e}"),
47            Self::Source(e) => write!(f, "chain source: {e}"),
48            Self::CommitSource(e) => write!(f, "commit source: {e}"),
49            Self::Invalid(e) => f.write_str(e),
50            Self::Busy(e) => write!(f, "archive busy: {e}"),
51            Self::PeerBusy => f.write_str("remote peer busy"),
52            Self::Transport(e) => write!(f, "peer transport: {e}"),
53            Self::DialDenied(limit) => write!(f, "dial denied by local connection limit ({limit})"),
54            Self::Stale => f.write_str("result belongs to a superseded chain view"),
55        }
56    }
57}
58
59impl std::error::Error for Error {
60    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
61        match self {
62            Self::Io(e) => Some(e),
63            Self::Database(e) => Some(e),
64            Self::Json(e) => Some(e),
65            Self::Source(e) => Some(e.as_ref()),
66            _ => None,
67        }
68    }
69}
70
71impl From<std::io::Error> for Error {
72    fn from(e: std::io::Error) -> Self {
73        Self::Io(e)
74    }
75}
76impl From<rusqlite::Error> for Error {
77    fn from(e: rusqlite::Error) -> Self {
78        Self::Database(e)
79    }
80}
81impl From<serde_json::Error> for Error {
82    fn from(e: serde_json::Error) -> Self {
83        Self::Json(e)
84    }
85}
86
87impl From<urma_node_client::Error> for Error {
88    fn from(error: urma_node_client::Error) -> Self {
89        match error {
90            urma_node_client::Error::Io(error) => Self::Io(error),
91            urma_node_client::Error::Json(error) => Self::Json(error),
92            urma_node_client::Error::Invalid(message) => Self::Invalid(message),
93            urma_node_client::Error::Busy(message) => Self::Busy(message),
94        }
95    }
96}