1#[derive(Debug)]
5pub struct Error {
6 pub(crate) inner: private::InnerError,
7}
8
9impl std::error::Error for Error {}
10
11impl std::fmt::Display for Error {
12 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13 write!(f, "{}", self.inner)
14 }
15}
16
17impl From<private::InnerError> for Error {
18 fn from(error: private::InnerError) -> Error {
19 Self { inner: error }
20 }
21}
22
23pub enum ParseUpdateError<Body> {
27 UnknownUpdate(crate::Message<Body>),
29
30 InvalidUpdate(crate::MessageHeader, Box<dyn std::error::Error + Send>),
35}
36
37pub enum RecvMessageError<Body> {
42 Other(Error),
44
45 UnknownStream(crate::Message<Body>),
47
48 UnknownRequest(crate::ReceivedRequestHandle<Body>, Body),
50
51 InvalidStream(crate::MessageHeader, Box<dyn std::error::Error + Send>),
56
57 InvalidRequest(crate::ReceivedRequestHandle<Body>, Box<dyn std::error::Error + Send>),
62}
63
64impl Error {
65 pub fn io_error(error: std::io::Error) -> Self {
67 private::InnerError::from(error).into()
68 }
69
70 pub fn message_too_short(message_len: usize) -> Self {
72 private::InnerError::MessageTooShort { message_len }.into()
73 }
74
75 pub fn invalid_message_type(value: u32) -> Self {
77 private::InnerError::InvalidMessageType { value }.into()
78 }
79
80 pub fn payload_too_large(body_len: usize, max_len: usize) -> Self {
82 private::InnerError::PayloadTooLarge { body_len, max_len }.into()
83 }
84
85 pub fn unexpected_service_id(service_id: i32) -> Self {
87 private::InnerError::UnexpectedServiceId { service_id }.into()
88 }
89
90 pub fn encode_failed(inner: Box<dyn std::error::Error + Send>) -> Self {
92 private::InnerError::EncodeFailed(inner).into()
93 }
94
95 pub fn decode_failed(inner: Box<dyn std::error::Error + Send>) -> Self {
97 private::InnerError::DecodeFailed(inner).into()
98 }
99
100 pub fn remote_error(message: String) -> Self {
106 private::InnerError::RemoteError(message).into()
107 }
108
109 pub fn custom(message: String) -> Self {
111 private::InnerError::Custom(message).into()
112 }
113
114 pub fn is_connection_aborted(&self) -> bool {
116 if let private::InnerError::Io(e) = &self.inner {
117 e.kind() == std::io::ErrorKind::ConnectionAborted
118 } else {
119 false
120 }
121 }
122
123 pub fn is_unexpected_message_type(&self) -> bool {
127 matches!(&self.inner, private::InnerError::UnexpectedMessageType(_))
128 }
129
130 pub fn is_remote_error(&self) -> bool {
134 matches!(&self.inner, private::InnerError::RemoteError(_))
135 }
136
137 pub fn as_remote_error(&self) -> Option<&str> {
141 if let private::InnerError::RemoteError(msg) = &self.inner {
142 Some(msg)
143 } else {
144 None
145 }
146 }
147
148 pub fn into_remote_error(self) -> Option<String> {
152 if let private::InnerError::RemoteError(msg) = self.inner {
153 Some(msg)
154 } else {
155 None
156 }
157 }
158}
159
160impl<Body> RecvMessageError<Body> {
161 pub fn is_connection_aborted(&self) -> bool {
163 if let Self::Other(e) = self {
164 e.is_connection_aborted()
165 } else {
166 false
167 }
168 }
169
170 pub fn request_handle(&self) -> Option<&crate::ReceivedRequestHandle<Body>> {
177 match self {
178 Self::Other(_error) => None,
179 Self::UnknownStream(_message) => None,
180 Self::UnknownRequest(request, _body) => Some(request),
181 Self::InvalidStream(_message, _error) => None,
182 Self::InvalidRequest(request, _error) => Some(request),
183 }
184 }
185
186 pub fn request_handle_mut(&mut self) -> Option<&mut crate::ReceivedRequestHandle<Body>> {
193 match self {
194 Self::Other(_error) => None,
195 Self::UnknownStream(_message) => None,
196 Self::UnknownRequest(request, _body) => Some(request),
197 Self::InvalidStream(_message, _error) => None,
198 Self::InvalidRequest(request, _error) => Some(request),
199 }
200 }
201}
202
203impl From<std::io::Error> for Error {
204 fn from(other: std::io::Error) -> Self {
205 Self::io_error(other)
206 }
207}
208
209impl<Body> From<Error> for RecvMessageError<Body> {
210 fn from(other: Error) -> Self {
211 Self::Other(other)
212 }
213}
214
215impl<Body> std::error::Error for ParseUpdateError<Body> {}
216impl<Body> std::error::Error for RecvMessageError<Body> {}
217
218impl<Body> std::fmt::Display for ParseUpdateError<Body> {
219 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
220 match self {
221 Self::UnknownUpdate(message) => write!(f, "received unknown update with service ID {}", message.header.service_id),
222 Self::InvalidUpdate(header, error) => write!(f, "received invalid update with service ID {}: {}", header.service_id, error),
223 }
224 }
225}
226
227impl<Body> std::fmt::Display for RecvMessageError<Body> {
228 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
229 match self {
230 Self::Other(e) => write!(f, "{}", e),
231 Self::UnknownStream(message) => write!(f, "received unknown stream message with service ID {}", message.header.service_id),
232 Self::InvalidStream(header, error) => write!(f, "received invalid stream message with service ID {}: {}", header.service_id, error),
233 Self::UnknownRequest(request, _body) => write!(f, "received unknown request message with service ID {}", request.service_id()),
234 Self::InvalidRequest(request, error) => write!(f, "received invalid request message with service ID {}: {}", request.service_id(), error),
235 }
236 }
237}
238
239impl<Body> std::fmt::Debug for ParseUpdateError<Body> {
240 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
241 match self {
242 Self::UnknownUpdate(message) => f.debug_tuple("UnknownUpdate").field(message).finish(),
243 Self::InvalidUpdate(header, error) => f.debug_tuple("InvalidUpdate").field(header).field(error).finish(),
244 }
245 }
246}
247
248impl<Body> std::fmt::Debug for RecvMessageError<Body> {
249 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
250 match self {
251 Self::Other(e) => f.debug_tuple("Other").field(e).finish(),
252 Self::UnknownStream(message) => f.debug_tuple("UnknownStream").field(message).finish(),
253 Self::UnknownRequest(request, _body) => f.debug_tuple("UnknownStream").field(request).finish(),
254 Self::InvalidStream(header, error) => f.debug_tuple("InvalidStread").field(header).field(error).finish(),
255 Self::InvalidRequest(request, error) => f.debug_tuple("InvalidRequest").field(request).field(error).finish(),
256 }
257 }
258}
259
260pub(crate) mod private {
261 use super::*;
262
263 pub(crate) fn connection_aborted() -> Error {
264 InnerError::from(std::io::Error::from(std::io::ErrorKind::ConnectionAborted)).into()
265 }
266
267 #[derive(Debug)]
268 #[doc(hidden)]
269 pub enum InnerError {
270 Io(std::io::Error),
272
273 MessageTooShort { message_len: usize },
275
276 InvalidMessageType {
278 value: u32,
280 },
281
282 PayloadTooLarge {
284 body_len: usize,
286
287 max_len: usize,
289 },
290
291 DuplicateRequestId {
293 request_id: u32,
295 },
296
297 UnknownRequestId {
299 request_id: u32,
301 },
302
303 UnexpectedMessageType(UnexpectedMessageType),
305
306 UnexpectedServiceId {
308 service_id: i32,
310 },
311
312 NoFreeRequestIdFound,
314
315 RequestClosed,
317
318 EncodeFailed(Box<dyn std::error::Error + Send>),
320
321 DecodeFailed(Box<dyn std::error::Error + Send>),
323
324 RemoteError(String),
326
327 Custom(String),
329 }
330
331 impl From<std::io::Error> for private::InnerError {
332 fn from(error: std::io::Error) -> Self {
333 private::InnerError::Io(error)
334 }
335 }
336
337 impl From<UnexpectedMessageType> for private::InnerError {
338 fn from(error: UnexpectedMessageType) -> Self {
339 private::InnerError::UnexpectedMessageType(error)
340 }
341 }
342
343 impl std::error::Error for InnerError {}
344
345 impl std::fmt::Display for InnerError {
346 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
347 match self {
348 InnerError::Io(error) => write!(f, "{}", error),
349 InnerError::MessageTooShort { message_len } => write!(
350 f,
351 "the message is too short to be valid: need at least {} for the header, got only {message_len} bytes",
352 crate::HEADER_LEN
353 ),
354 InnerError::InvalidMessageType { value } => write!(f, "invalid message type: expected a value in the range [0..4], got {value}"),
355 InnerError::PayloadTooLarge { body_len, max_len } => {
356 write!(f, "payload too large: maximum payload size is {max_len}, got {body_len}")
357 },
358 InnerError::DuplicateRequestId { request_id } => write!(
359 f,
360 "duplicate request ID: request ID {request_id} is already associated with an open request"
361 ),
362 InnerError::UnknownRequestId { request_id } => {
363 write!(f, "unknown request ID: request ID {request_id} is not associated with an open request")
364 },
365 InnerError::UnexpectedMessageType(error) => write!(f, "{}", error),
366 InnerError::UnexpectedServiceId { service_id } => write!(f, "unexpected service ID: {service_id}"),
367 InnerError::NoFreeRequestIdFound => write!(f, "no free request ID was found"),
368 InnerError::RequestClosed => write!(f, "the request is already closed"),
369 InnerError::EncodeFailed(error) => write!(f, "{}", error),
370 InnerError::DecodeFailed(error) => write!(f, "{}", error),
371 InnerError::RemoteError(error) => write!(f, "{}", error),
372 InnerError::Custom(error) => write!(f, "{}", error),
373 }
374 }
375 }
376
377 #[allow(dead_code)] pub fn check_message_too_short(message_len: usize) -> Result<(), InnerError> {
380 if message_len >= crate::HEADER_LEN as usize {
381 Ok(())
382 } else {
383 Err(InnerError::MessageTooShort { message_len })
384 }
385 }
386
387 pub fn check_payload_too_large(body_len: usize, max_len: usize) -> Result<(), InnerError> {
389 if body_len <= max_len {
390 Ok(())
391 } else {
392 Err(InnerError::PayloadTooLarge { body_len, max_len })
393 }
394 }
395
396 #[derive(Debug, Clone)]
398 pub struct UnexpectedMessageType {
399 pub value: crate::MessageType,
401
402 pub expected: crate::MessageType,
404 }
405
406 impl std::error::Error for UnexpectedMessageType {}
407
408 impl std::fmt::Display for UnexpectedMessageType {
409 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
410 let to_str = |kind| match kind {
414 crate::MessageType::Request => "a request message",
415 crate::MessageType::Response => "a response message",
416 crate::MessageType::RequesterUpdate => "an update message",
417 crate::MessageType::ResponderUpdate => "an update message",
418 crate::MessageType::Stream => "a streaming message",
419 };
420 write!(
421 f,
422 "unexpected message type: expected {}, got {}",
423 to_str(self.expected),
424 to_str(self.value)
425 )
426 }
427 }
428}