actr_runtime/transport/
error.rs

1//! Network layer error definitions
2
3use thiserror::Error;
4
5/// Network layer error types
6#[derive(Error, Debug)]
7pub enum NetworkError {
8    /// Connection error
9    #[error("Connection error: {0}")]
10    ConnectionError(String),
11
12    /// Signaling error
13    #[error("Signaling error: {0}")]
14    SignalingError(String),
15
16    /// WebRTC error
17    #[error("WebRTC error: {0}")]
18    WebRtcError(String),
19
20    /// Protocol error
21    #[error("Protocol error: {0}")]
22    ProtocolError(String),
23
24    /// Serialization error
25    #[error("Serialization error: {0}")]
26    SerializationError(String),
27
28    /// Deserialization error
29    #[error("Deserialization error: {0}")]
30    DeserializationError(String),
31
32    /// Timeout error
33    #[error("Timeout error: {0}")]
34    TimeoutError(String),
35
36    /// Authentication error
37    #[error("Authentication error: {0}")]
38    AuthenticationError(String),
39
40    /// Permission error
41    #[error("Permission error: {0}")]
42    PermissionError(String),
43
44    /// Configuration error
45    #[error("Configuration error: {0}")]
46    ConfigurationError(String),
47
48    /// Resource exhausted error
49    #[error("Resource exhausted: {0}")]
50    ResourceExhaustedError(String),
51
52    /// Network unreachable error
53    #[error("Network unreachable: {0}")]
54    NetworkUnreachableError(String),
55
56    /// Service discovery error
57    #[error("Service discovery error: {0}")]
58    ServiceDiscoveryError(String),
59
60    /// NAT traversal error
61    #[error("NAT traversal error: {0}")]
62    NatTraversalError(String),
63
64    /// Data channel error
65    #[error("Data channel error: {0}")]
66    DataChannelError(String),
67
68    /// Broadcast error
69    #[error("Broadcast error: {0}")]
70    BroadcastError(String),
71
72    /// ICE error
73    #[error("ICE error: {0}")]
74    IceError(String),
75
76    /// DTLS error
77    #[error("DTLS error: {0}")]
78    DtlsError(String),
79
80    /// STUN/TURN error
81    #[error("STUN/TURN error: {0}")]
82    StunTurnError(String),
83
84    /// WebSocket error
85    #[error("WebSocket error: {0}")]
86    WebSocketError(String),
87
88    /// Connection not found error
89    #[error("Connection not found: {0}")]
90    ConnectionNotFound(String),
91
92    /// Connection closed error (e.g., cancelled during creation)
93    #[error("Connection closed: {0}")]
94    ConnectionClosed(String),
95
96    /// Feature not implemented error
97    #[error("Not implemented: {0}")]
98    NotImplemented(String),
99
100    /// Channel closed error
101    #[error("Channel closed: {0}")]
102    ChannelClosed(String),
103
104    /// Send error
105    #[error("Send error: {0}")]
106    SendError(String),
107
108    /// No route error
109    #[error("No route: {0}")]
110    NoRoute(String),
111
112    /// Invalid operation error
113    #[error("Invalid operation: {0}")]
114    InvalidOperation(String),
115
116    /// Invalid argument error
117    #[error("Invalid argument: {0}")]
118    InvalidArgument(String),
119
120    /// Channel not found error
121    #[error("Channel not found: {0}")]
122    ChannelNotFound(String),
123
124    /// IO error
125    #[error("IO error: {0}")]
126    IoError(#[from] std::io::Error),
127
128    /// URL parse error
129    #[error("URL parse error: {0}")]
130    UrlParseError(#[from] url::ParseError),
131
132    /// JSON error
133    #[error("JSON error: {0}")]
134    JsonError(#[from] serde_json::Error),
135
136    /// Timeout error
137    #[error("Timeout error: {0}")]
138    Timeout(String),
139
140    /// Other error
141    #[error("Other error: {0}")]
142    Other(#[from] anyhow::Error),
143}
144
145impl NetworkError {
146    /// Check if error is retryable
147    pub fn is_retryable(&self) -> bool {
148        matches!(
149            self,
150            NetworkError::ConnectionError(_)
151                | NetworkError::TimeoutError(_)
152                | NetworkError::NetworkUnreachableError(_)
153                | NetworkError::ResourceExhaustedError(_)
154        )
155    }
156
157    /// Check if error is temporary
158    pub fn is_temporary(&self) -> bool {
159        matches!(
160            self,
161            NetworkError::ConnectionError(_)
162                | NetworkError::TimeoutError(_)
163                | NetworkError::NetworkUnreachableError(_)
164                | NetworkError::ResourceExhaustedError(_)
165        )
166    }
167
168    /// Check if error is fatal
169    pub fn is_fatal(&self) -> bool {
170        matches!(
171            self,
172            NetworkError::AuthenticationError(_)
173                | NetworkError::PermissionError(_)
174                | NetworkError::ConfigurationError(_)
175        )
176    }
177
178    /// Get error category
179    pub fn category(&self) -> &'static str {
180        match self {
181            NetworkError::ConnectionError(_) => "connection",
182            NetworkError::SignalingError(_) => "signaling",
183            NetworkError::WebRtcError(_) => "webrtc",
184            NetworkError::ProtocolError(_) => "protocol",
185            NetworkError::SerializationError(_) | NetworkError::DeserializationError(_) => {
186                "serialization"
187            }
188            NetworkError::TimeoutError(_) => "timeout",
189            NetworkError::AuthenticationError(_) => "authentication",
190            NetworkError::PermissionError(_) => "permission",
191            NetworkError::ConfigurationError(_) => "configuration",
192            NetworkError::ResourceExhaustedError(_) => "resource_exhausted",
193            NetworkError::NetworkUnreachableError(_) => "network_unreachable",
194            NetworkError::ServiceDiscoveryError(_) => "service_discovery",
195            NetworkError::NatTraversalError(_) => "nat_traversal",
196            NetworkError::DataChannelError(_) => "data_channel",
197            NetworkError::IceError(_) => "ice",
198            NetworkError::DtlsError(_) => "dtls",
199            NetworkError::StunTurnError(_) => "stun_turn",
200            NetworkError::WebSocketError(_) => "websocket",
201            NetworkError::ConnectionNotFound(_) => "connection_not_found",
202            NetworkError::ConnectionClosed(_) => "connection_closed",
203            NetworkError::NotImplemented(_) => "not_implemented",
204            NetworkError::ChannelClosed(_) => "channel_closed",
205            NetworkError::SendError(_) => "send_error",
206            NetworkError::NoRoute(_) => "no_route",
207            NetworkError::InvalidOperation(_) => "invalid_operation",
208            NetworkError::InvalidArgument(_) => "invalid_argument",
209            NetworkError::ChannelNotFound(_) => "channel_not_found",
210            NetworkError::IoError(_) => "io",
211            NetworkError::UrlParseError(_) => "url_parse",
212            NetworkError::JsonError(_) => "json",
213            NetworkError::BroadcastError(_) => "broadcast",
214            NetworkError::Timeout(_) => "timeout",
215            NetworkError::Other(_) => "other",
216        }
217    }
218
219    /// Get error severity (1-10, 10 is most severe)
220    pub fn severity(&self) -> u8 {
221        match self {
222            NetworkError::ConfigurationError(_)
223            | NetworkError::AuthenticationError(_)
224            | NetworkError::PermissionError(_) => 10,
225
226            NetworkError::WebRtcError(_)
227            | NetworkError::SignalingError(_)
228            | NetworkError::ProtocolError(_) => 8,
229
230            NetworkError::ConnectionError(_) | NetworkError::NetworkUnreachableError(_) => 7,
231
232            NetworkError::NatTraversalError(_)
233            | NetworkError::IceError(_)
234            | NetworkError::DtlsError(_) => 6,
235
236            NetworkError::TimeoutError(_) | NetworkError::ResourceExhaustedError(_) => 5,
237
238            NetworkError::ServiceDiscoveryError(_)
239            | NetworkError::DataChannelError(_)
240            | NetworkError::BroadcastError(_) => 4,
241
242            NetworkError::SerializationError(_) | NetworkError::DeserializationError(_) => 3,
243
244            NetworkError::WebSocketError(_) | NetworkError::StunTurnError(_) => 3,
245
246            NetworkError::ConnectionNotFound(_)
247            | NetworkError::ConnectionClosed(_)
248            | NetworkError::ChannelClosed(_)
249            | NetworkError::SendError(_)
250            | NetworkError::NoRoute(_)
251            | NetworkError::ChannelNotFound(_) => 4,
252
253            NetworkError::InvalidOperation(_) | NetworkError::InvalidArgument(_) => 6,
254
255            NetworkError::NotImplemented(_) => 8,
256
257            NetworkError::IoError(_)
258            | NetworkError::UrlParseError(_)
259            | NetworkError::JsonError(_)
260            | NetworkError::Timeout(_) => 2,
261
262            NetworkError::Other(_) => 1,
263        }
264    }
265}
266
267// TODO: Implement UnifiedError trait (when actr-protocol provides error_unified module)
268// impl UnifiedError for NetworkError { ... }
269
270/// Network layer result type
271pub type NetworkResult<T> = Result<T, NetworkError>;
272
273/// Convert from actor error to network error
274impl From<actr_protocol::ActrError> for NetworkError {
275    fn from(err: actr_protocol::ActrError) -> Self {
276        NetworkError::Other(anyhow::anyhow!("Actor error: {err}"))
277    }
278}
279
280/// Convert from WebRTC error
281impl From<webrtc::Error> for NetworkError {
282    fn from(err: webrtc::Error) -> Self {
283        NetworkError::WebRtcError(err.to_string())
284    }
285}
286
287/// Convert from WebSocket error
288impl From<tokio_tungstenite::tungstenite::Error> for NetworkError {
289    fn from(err: tokio_tungstenite::tungstenite::Error) -> Self {
290        NetworkError::WebSocketError(err.to_string())
291    }
292}
293
294/// Convert from protobuf encode error
295impl From<actr_protocol::prost::EncodeError> for NetworkError {
296    fn from(err: actr_protocol::prost::EncodeError) -> Self {
297        NetworkError::SerializationError(err.to_string())
298    }
299}
300
301/// Convert from protobuf decode error
302impl From<actr_protocol::prost::DecodeError> for NetworkError {
303    fn from(err: actr_protocol::prost::DecodeError) -> Self {
304        NetworkError::DeserializationError(err.to_string())
305    }
306}
307
308// TODO: In future, if error statistics needed, can add ErrorStats struct
309// Recommend using arrays instead of HashMap (error categories and severities are fixed)