airsprotocols_mcp/transport/
error.rs1#[derive(Debug, thiserror::Error)]
11pub enum TransportError {
12 #[error("I/O error: {0}")]
14 Io(#[from] std::io::Error),
15
16 #[error("Transport connection is closed")]
18 Closed,
19
20 #[error("Connection limit exceeded: {0}")]
22 ConnectionLimit(String),
23
24 #[error("Invalid connection: {0}")]
26 InvalidConnection(String),
27
28 #[error("Session error: {0}")]
30 SessionError(String),
31
32 #[error("Message format error: {message}")]
34 Format { message: String },
35
36 #[error("Connection timeout after {duration_ms}ms")]
38 Timeout { duration_ms: u64 },
39
40 #[error("Buffer overflow: {details}")]
42 BufferOverflow { details: String },
43
44 #[error("Message too large: {size} bytes (max: {max_size} bytes)")]
46 MessageTooLarge { size: usize, max_size: usize },
47
48 #[error("Incomplete message received")]
50 IncompleteMessage,
51
52 #[error("Parse error: {0}")]
54 ParseError(String),
55
56 #[error("Serialization error: {0}")]
58 SerializationError(String),
59
60 #[error("Transport error: {details}")]
62 Other { details: String },
63}
64
65impl TransportError {
66 pub fn format(message: impl Into<String>) -> Self {
68 Self::Format {
69 message: message.into(),
70 }
71 }
72
73 pub fn timeout(duration_ms: u64) -> Self {
75 Self::Timeout { duration_ms }
76 }
77
78 pub fn buffer_overflow(details: impl Into<String>) -> Self {
80 Self::BufferOverflow {
81 details: details.into(),
82 }
83 }
84
85 pub fn message_too_large(size: usize, max_size: usize) -> Self {
87 Self::MessageTooLarge { size, max_size }
88 }
89
90 pub fn incomplete_message() -> Self {
92 Self::IncompleteMessage
93 }
94
95 pub fn parse_error(error: impl Into<String>) -> Self {
97 Self::ParseError(error.into())
98 }
99
100 pub fn serialization_error(error: impl Into<String>) -> Self {
102 Self::SerializationError(error.into())
103 }
104
105 pub fn other(details: impl Into<String>) -> Self {
107 Self::Other {
108 details: details.into(),
109 }
110 }
111
112 pub fn closed() -> Self {
114 Self::Closed
115 }
116
117 pub fn connection_limit(message: impl Into<String>) -> Self {
119 Self::ConnectionLimit(message.into())
120 }
121
122 pub fn invalid_connection(message: impl Into<String>) -> Self {
124 Self::InvalidConnection(message.into())
125 }
126
127 pub fn session_error(message: impl Into<String>) -> Self {
129 Self::SessionError(message.into())
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 fn test_transport_error_creation() {
139 let err = TransportError::format("invalid JSON");
141 assert!(matches!(err, TransportError::Format { .. }));
142 assert_eq!(err.to_string(), "Message format error: invalid JSON");
143
144 let err = TransportError::timeout(5000);
146 assert!(matches!(err, TransportError::Timeout { duration_ms: 5000 }));
147 assert_eq!(err.to_string(), "Connection timeout after 5000ms");
148
149 let err = TransportError::buffer_overflow("message too large");
151 assert!(matches!(err, TransportError::BufferOverflow { .. }));
152 assert_eq!(err.to_string(), "Buffer overflow: message too large");
153
154 let err = TransportError::other("custom transport error");
156 assert!(matches!(err, TransportError::Other { .. }));
157 assert_eq!(err.to_string(), "Transport error: custom transport error");
158
159 let err = TransportError::Closed;
161 assert_eq!(err.to_string(), "Transport connection is closed");
162 }
163
164 #[test]
165 fn test_transport_error_from_io() {
166 let io_err = std::io::Error::new(std::io::ErrorKind::BrokenPipe, "pipe broken");
167 let transport_err = TransportError::from(io_err);
168
169 assert!(matches!(transport_err, TransportError::Io(_)));
170 assert!(transport_err.to_string().contains("pipe broken"));
171 }
172
173 #[test]
174 fn test_transport_error_traits() {
175 let err = TransportError::Closed;
176
177 assert!(std::error::Error::source(&err).is_none());
179
180 fn assert_send_sync<T: Send + Sync>() {}
182 assert_send_sync::<TransportError>();
183
184 let debug_str = format!("{err:?}");
186 assert!(!debug_str.is_empty());
187 }
188}