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    /// A dial authenticated this node itself, e.g. a seed resolving to us.
18    LocalPeer,
19    Stale,
20}
21
22/// Which local admission limit refused a connection.
23#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub enum DialLimit {
25    /// Too many connections still handshaking in that direction.
26    Pending,
27    /// Every established slot in that direction (or in total) is taken.
28    Established,
29    /// The peer already holds an established connection.
30    Duplicate,
31}
32
33impl std::fmt::Display for DialLimit {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        f.write_str(match self {
36            Self::Pending => "pending connection limit",
37            Self::Established => "established connection limit",
38            Self::Duplicate => "peer already connected",
39        })
40    }
41}
42
43impl std::fmt::Display for Error {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        match self {
46            Self::Io(e) => write!(f, "archive I/O: {e}"),
47            Self::Database(e) => write!(f, "archive database: {e}"),
48            Self::Json(e) => write!(f, "archive encoding: {e}"),
49            Self::Source(e) => write!(f, "chain source: {e}"),
50            Self::CommitSource(e) => write!(f, "commit source: {e}"),
51            Self::Invalid(e) => f.write_str(e),
52            Self::Busy(e) => write!(f, "archive busy: {e}"),
53            Self::PeerBusy => f.write_str("remote peer busy"),
54            Self::Transport(e) => write!(f, "peer transport: {e}"),
55            Self::DialDenied(limit) => write!(f, "dial denied by local connection limit ({limit})"),
56            Self::LocalPeer => f.write_str("dial reached this node itself"),
57            Self::Stale => f.write_str("result belongs to a superseded chain view"),
58        }
59    }
60}
61
62impl std::error::Error for Error {
63    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
64        match self {
65            Self::Io(e) => Some(e),
66            Self::Database(e) => Some(e),
67            Self::Json(e) => Some(e),
68            Self::Source(e) => Some(e.as_ref()),
69            _ => None,
70        }
71    }
72}
73
74impl From<std::io::Error> for Error {
75    fn from(e: std::io::Error) -> Self {
76        Self::Io(e)
77    }
78}
79impl From<rusqlite::Error> for Error {
80    fn from(e: rusqlite::Error) -> Self {
81        Self::Database(e)
82    }
83}
84impl From<serde_json::Error> for Error {
85    fn from(e: serde_json::Error) -> Self {
86        Self::Json(e)
87    }
88}
89
90impl From<urma_node_client::Error> for Error {
91    fn from(error: urma_node_client::Error) -> Self {
92        match error {
93            urma_node_client::Error::Io(error) => Self::Io(error),
94            urma_node_client::Error::Json(error) => Self::Json(error),
95            urma_node_client::Error::Invalid(message) => Self::Invalid(message),
96            urma_node_client::Error::Busy(message) => Self::Busy(message),
97        }
98    }
99}