Skip to main content

brainwires_agent_network/network/
error.rs

1use thiserror::Error;
2
3/// Errors that can occur within the networking stack.
4///
5/// Covers all five layers: identity, transport, routing, discovery, and
6/// application.
7#[derive(Debug, Clone, Error)]
8pub enum NetworkError {
9    // ── Identity layer ──────────────────────────────────────────────────
10    /// An agent identity could not be resolved.
11    #[error("identity not found: {0}")]
12    IdentityNotFound(String),
13
14    /// Credential verification failed.
15    #[error("authentication failed: {0}")]
16    AuthenticationFailed(String),
17
18    // ── Transport layer ─────────────────────────────────────────────────
19    /// A transport-level connection failure.
20    #[error("connection failed: {0}")]
21    ConnectionFailed(String),
22
23    /// A transport is not connected when an operation requires it.
24    #[error("not connected: {0}")]
25    NotConnected(String),
26
27    /// Sending a message failed at the transport level.
28    #[error("send failed: {0}")]
29    SendFailed(String),
30
31    /// Receiving a message failed at the transport level.
32    #[error("receive failed: {0}")]
33    ReceiveFailed(String),
34
35    // ── Routing layer ───────────────────────────────────────────────────
36    /// A message could not be routed to its destination.
37    #[error("routing failed: {0}")]
38    RoutingFailed(String),
39
40    /// No route exists to the requested peer.
41    #[error("no route to peer: {0}")]
42    NoRoute(String),
43
44    // ── Discovery layer ─────────────────────────────────────────────────
45    /// Peer discovery failed.
46    #[error("discovery failed: {0}")]
47    DiscoveryFailed(String),
48
49    /// Agent registration with a discovery service failed.
50    #[error("registration failed: {0}")]
51    RegistrationFailed(String),
52
53    // ── Application layer ───────────────────────────────────────────────
54    /// A peer/node was not found in the peer table.
55    #[error("peer not found: {0}")]
56    PeerNotFound(String),
57
58    /// A federation request was denied by policy.
59    #[error("federation denied: {0}")]
60    FederationDenied(String),
61
62    /// The network manager is in an invalid state for the requested operation.
63    #[error("invalid state: {0}")]
64    InvalidState(String),
65
66    // ── General ─────────────────────────────────────────────────────────
67    /// An internal or unexpected error.
68    #[error("internal error: {0}")]
69    Internal(String),
70
71    /// Operation timed out.
72    #[error("timeout: {0}")]
73    Timeout(String),
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn error_display_messages() {
82        let cases: Vec<(NetworkError, &str)> = vec![
83            (
84                NetworkError::IdentityNotFound("agent-x".into()),
85                "identity not found: agent-x",
86            ),
87            (
88                NetworkError::ConnectionFailed("refused".into()),
89                "connection failed: refused",
90            ),
91            (
92                NetworkError::RoutingFailed("no path".into()),
93                "routing failed: no path",
94            ),
95            (
96                NetworkError::DiscoveryFailed("timeout".into()),
97                "discovery failed: timeout",
98            ),
99            (
100                NetworkError::PeerNotFound("abc".into()),
101                "peer not found: abc",
102            ),
103            (
104                NetworkError::FederationDenied("policy".into()),
105                "federation denied: policy",
106            ),
107            (NetworkError::Timeout("5s".into()), "timeout: 5s"),
108        ];
109
110        for (err, expected) in cases {
111            assert_eq!(err.to_string(), expected);
112        }
113    }
114
115    #[test]
116    fn error_is_std_error() {
117        let err = NetworkError::Internal("test".into());
118        let _: &dyn std::error::Error = &err;
119    }
120
121    #[test]
122    fn error_clone() {
123        let err = NetworkError::SendFailed("broken pipe".into());
124        let cloned = err.clone();
125        assert_eq!(err.to_string(), cloned.to_string());
126    }
127}