openlibspot_core/
error.rs

1use std::{
2    error, fmt,
3    num::{ParseIntError, TryFromIntError},
4    str::Utf8Error,
5    string::FromUtf8Error,
6};
7
8use base64::DecodeError;
9use http::{
10    header::{InvalidHeaderName, InvalidHeaderValue, ToStrError},
11    method::InvalidMethod,
12    status::InvalidStatusCode,
13    uri::{InvalidUri, InvalidUriParts},
14};
15use protobuf::Error as ProtobufError;
16use thiserror::Error;
17use tokio::sync::{
18    mpsc::error::SendError, oneshot::error::RecvError, AcquireError, TryAcquireError,
19};
20use url::ParseError;
21
22#[cfg(feature = "with-dns-sd")]
23use dns_sd::DNSError;
24
25#[derive(Debug)]
26pub struct Error {
27    pub kind: ErrorKind,
28    pub error: Box<dyn error::Error + Send + Sync>,
29}
30
31#[derive(Clone, Copy, Debug, Eq, Error, Hash, Ord, PartialEq, PartialOrd)]
32pub enum ErrorKind {
33    #[error("The operation was cancelled by the caller")]
34    Cancelled = 1,
35
36    #[error("Unknown error")]
37    Unknown = 2,
38
39    #[error("Client specified an invalid argument")]
40    InvalidArgument = 3,
41
42    #[error("Deadline expired before operation could complete")]
43    DeadlineExceeded = 4,
44
45    #[error("Requested entity was not found")]
46    NotFound = 5,
47
48    #[error("Attempt to create entity that already exists")]
49    AlreadyExists = 6,
50
51    #[error("Permission denied")]
52    PermissionDenied = 7,
53
54    #[error("No valid authentication credentials")]
55    Unauthenticated = 16,
56
57    #[error("Resource has been exhausted")]
58    ResourceExhausted = 8,
59
60    #[error("Invalid state")]
61    FailedPrecondition = 9,
62
63    #[error("Operation aborted")]
64    Aborted = 10,
65
66    #[error("Operation attempted past the valid range")]
67    OutOfRange = 11,
68
69    #[error("Not implemented")]
70    Unimplemented = 12,
71
72    #[error("Internal error")]
73    Internal = 13,
74
75    #[error("Service unavailable")]
76    Unavailable = 14,
77
78    #[error("Unrecoverable data loss or corruption")]
79    DataLoss = 15,
80
81    #[error("Operation must not be used")]
82    DoNotUse = -1,
83}
84
85#[derive(Debug, Error)]
86struct ErrorMessage(String);
87
88impl fmt::Display for ErrorMessage {
89    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90        write!(f, "{}", self.0)
91    }
92}
93
94impl Error {
95    pub fn new<E>(kind: ErrorKind, error: E) -> Error
96    where
97        E: Into<Box<dyn error::Error + Send + Sync>>,
98    {
99        Self {
100            kind,
101            error: error.into(),
102        }
103    }
104
105    pub fn aborted<E>(error: E) -> Error
106    where
107        E: Into<Box<dyn error::Error + Send + Sync>>,
108    {
109        Self {
110            kind: ErrorKind::Aborted,
111            error: error.into(),
112        }
113    }
114
115    pub fn already_exists<E>(error: E) -> Error
116    where
117        E: Into<Box<dyn error::Error + Send + Sync>>,
118    {
119        Self {
120            kind: ErrorKind::AlreadyExists,
121            error: error.into(),
122        }
123    }
124
125    pub fn cancelled<E>(error: E) -> Error
126    where
127        E: Into<Box<dyn error::Error + Send + Sync>>,
128    {
129        Self {
130            kind: ErrorKind::Cancelled,
131            error: error.into(),
132        }
133    }
134
135    pub fn data_loss<E>(error: E) -> Error
136    where
137        E: Into<Box<dyn error::Error + Send + Sync>>,
138    {
139        Self {
140            kind: ErrorKind::DataLoss,
141            error: error.into(),
142        }
143    }
144
145    pub fn deadline_exceeded<E>(error: E) -> Error
146    where
147        E: Into<Box<dyn error::Error + Send + Sync>>,
148    {
149        Self {
150            kind: ErrorKind::DeadlineExceeded,
151            error: error.into(),
152        }
153    }
154
155    pub fn do_not_use<E>(error: E) -> Error
156    where
157        E: Into<Box<dyn error::Error + Send + Sync>>,
158    {
159        Self {
160            kind: ErrorKind::DoNotUse,
161            error: error.into(),
162        }
163    }
164
165    pub fn failed_precondition<E>(error: E) -> Error
166    where
167        E: Into<Box<dyn error::Error + Send + Sync>>,
168    {
169        Self {
170            kind: ErrorKind::FailedPrecondition,
171            error: error.into(),
172        }
173    }
174
175    pub fn internal<E>(error: E) -> Error
176    where
177        E: Into<Box<dyn error::Error + Send + Sync>>,
178    {
179        Self {
180            kind: ErrorKind::Internal,
181            error: error.into(),
182        }
183    }
184
185    pub fn invalid_argument<E>(error: E) -> Error
186    where
187        E: Into<Box<dyn error::Error + Send + Sync>>,
188    {
189        Self {
190            kind: ErrorKind::InvalidArgument,
191            error: error.into(),
192        }
193    }
194
195    pub fn not_found<E>(error: E) -> Error
196    where
197        E: Into<Box<dyn error::Error + Send + Sync>>,
198    {
199        Self {
200            kind: ErrorKind::NotFound,
201            error: error.into(),
202        }
203    }
204
205    pub fn out_of_range<E>(error: E) -> Error
206    where
207        E: Into<Box<dyn error::Error + Send + Sync>>,
208    {
209        Self {
210            kind: ErrorKind::OutOfRange,
211            error: error.into(),
212        }
213    }
214
215    pub fn permission_denied<E>(error: E) -> Error
216    where
217        E: Into<Box<dyn error::Error + Send + Sync>>,
218    {
219        Self {
220            kind: ErrorKind::PermissionDenied,
221            error: error.into(),
222        }
223    }
224
225    pub fn resource_exhausted<E>(error: E) -> Error
226    where
227        E: Into<Box<dyn error::Error + Send + Sync>>,
228    {
229        Self {
230            kind: ErrorKind::ResourceExhausted,
231            error: error.into(),
232        }
233    }
234
235    pub fn unauthenticated<E>(error: E) -> Error
236    where
237        E: Into<Box<dyn error::Error + Send + Sync>>,
238    {
239        Self {
240            kind: ErrorKind::Unauthenticated,
241            error: error.into(),
242        }
243    }
244
245    pub fn unavailable<E>(error: E) -> Error
246    where
247        E: Into<Box<dyn error::Error + Send + Sync>>,
248    {
249        Self {
250            kind: ErrorKind::Unavailable,
251            error: error.into(),
252        }
253    }
254
255    pub fn unimplemented<E>(error: E) -> Error
256    where
257        E: Into<Box<dyn error::Error + Send + Sync>>,
258    {
259        Self {
260            kind: ErrorKind::Unimplemented,
261            error: error.into(),
262        }
263    }
264
265    pub fn unknown<E>(error: E) -> Error
266    where
267        E: Into<Box<dyn error::Error + Send + Sync>>,
268    {
269        Self {
270            kind: ErrorKind::Unknown,
271            error: error.into(),
272        }
273    }
274}
275
276impl std::error::Error for Error {
277    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
278        self.error.source()
279    }
280}
281
282impl fmt::Display for Error {
283    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
284        write!(fmt, "{} {{ ", self.kind)?;
285        self.error.fmt(fmt)?;
286        write!(fmt, " }}")
287    }
288}
289
290impl From<DecodeError> for Error {
291    fn from(err: DecodeError) -> Self {
292        Self::new(ErrorKind::FailedPrecondition, err)
293    }
294}
295
296#[cfg(feature = "with-dns-sd")]
297impl From<DNSError> for Error {
298    fn from(err: DNSError) -> Self {
299        Self::new(ErrorKind::Unavailable, err)
300    }
301}
302
303impl From<http::Error> for Error {
304    fn from(err: http::Error) -> Self {
305        if err.is::<InvalidHeaderName>()
306            || err.is::<InvalidHeaderValue>()
307            || err.is::<InvalidMethod>()
308            || err.is::<InvalidUri>()
309            || err.is::<InvalidUriParts>()
310        {
311            return Self::new(ErrorKind::InvalidArgument, err);
312        }
313
314        if err.is::<InvalidStatusCode>() {
315            return Self::new(ErrorKind::FailedPrecondition, err);
316        }
317
318        Self::new(ErrorKind::Unknown, err)
319    }
320}
321
322impl From<hyper::Error> for Error {
323    fn from(err: hyper::Error) -> Self {
324        if err.is_parse() || err.is_parse_too_large() || err.is_parse_status() || err.is_user() {
325            return Self::new(ErrorKind::Internal, err);
326        }
327
328        if err.is_canceled() {
329            return Self::new(ErrorKind::Cancelled, err);
330        }
331
332        if err.is_connect() {
333            return Self::new(ErrorKind::Unavailable, err);
334        }
335
336        if err.is_incomplete_message() {
337            return Self::new(ErrorKind::DataLoss, err);
338        }
339
340        if err.is_body_write_aborted() || err.is_closed() {
341            return Self::new(ErrorKind::Aborted, err);
342        }
343
344        if err.is_timeout() {
345            return Self::new(ErrorKind::DeadlineExceeded, err);
346        }
347
348        Self::new(ErrorKind::Unknown, err)
349    }
350}
351
352impl From<time::error::Parse> for Error {
353    fn from(err: time::error::Parse) -> Self {
354        Self::new(ErrorKind::FailedPrecondition, err)
355    }
356}
357
358impl From<quick_xml::Error> for Error {
359    fn from(err: quick_xml::Error) -> Self {
360        Self::new(ErrorKind::FailedPrecondition, err)
361    }
362}
363
364impl From<serde_json::Error> for Error {
365    fn from(err: serde_json::Error) -> Self {
366        Self::new(ErrorKind::FailedPrecondition, err)
367    }
368}
369
370impl From<std::io::Error> for Error {
371    fn from(err: std::io::Error) -> Self {
372        use std::io::ErrorKind as IoErrorKind;
373        match err.kind() {
374            IoErrorKind::NotFound => Self::new(ErrorKind::NotFound, err),
375            IoErrorKind::PermissionDenied => Self::new(ErrorKind::PermissionDenied, err),
376            IoErrorKind::AddrInUse | IoErrorKind::AlreadyExists => {
377                Self::new(ErrorKind::AlreadyExists, err)
378            }
379            IoErrorKind::AddrNotAvailable
380            | IoErrorKind::ConnectionRefused
381            | IoErrorKind::NotConnected => Self::new(ErrorKind::Unavailable, err),
382            IoErrorKind::BrokenPipe
383            | IoErrorKind::ConnectionReset
384            | IoErrorKind::ConnectionAborted => Self::new(ErrorKind::Aborted, err),
385            IoErrorKind::Interrupted | IoErrorKind::WouldBlock => {
386                Self::new(ErrorKind::Cancelled, err)
387            }
388            IoErrorKind::InvalidData | IoErrorKind::UnexpectedEof => {
389                Self::new(ErrorKind::FailedPrecondition, err)
390            }
391            IoErrorKind::TimedOut => Self::new(ErrorKind::DeadlineExceeded, err),
392            IoErrorKind::InvalidInput => Self::new(ErrorKind::InvalidArgument, err),
393            IoErrorKind::WriteZero => Self::new(ErrorKind::ResourceExhausted, err),
394            _ => Self::new(ErrorKind::Unknown, err),
395        }
396    }
397}
398
399impl From<FromUtf8Error> for Error {
400    fn from(err: FromUtf8Error) -> Self {
401        Self::new(ErrorKind::FailedPrecondition, err)
402    }
403}
404
405impl From<InvalidHeaderValue> for Error {
406    fn from(err: InvalidHeaderValue) -> Self {
407        Self::new(ErrorKind::InvalidArgument, err)
408    }
409}
410
411impl From<InvalidUri> for Error {
412    fn from(err: InvalidUri) -> Self {
413        Self::new(ErrorKind::InvalidArgument, err)
414    }
415}
416
417impl From<ParseError> for Error {
418    fn from(err: ParseError) -> Self {
419        Self::new(ErrorKind::FailedPrecondition, err)
420    }
421}
422
423impl From<ParseIntError> for Error {
424    fn from(err: ParseIntError) -> Self {
425        Self::new(ErrorKind::FailedPrecondition, err)
426    }
427}
428
429impl From<TryFromIntError> for Error {
430    fn from(err: TryFromIntError) -> Self {
431        Self::new(ErrorKind::FailedPrecondition, err)
432    }
433}
434
435impl From<ProtobufError> for Error {
436    fn from(err: ProtobufError) -> Self {
437        Self::new(ErrorKind::FailedPrecondition, err)
438    }
439}
440
441impl From<RecvError> for Error {
442    fn from(err: RecvError) -> Self {
443        Self::new(ErrorKind::Internal, err)
444    }
445}
446
447impl<T> From<SendError<T>> for Error {
448    fn from(err: SendError<T>) -> Self {
449        Self {
450            kind: ErrorKind::Internal,
451            error: ErrorMessage(err.to_string()).into(),
452        }
453    }
454}
455
456impl From<AcquireError> for Error {
457    fn from(err: AcquireError) -> Self {
458        Self {
459            kind: ErrorKind::ResourceExhausted,
460            error: ErrorMessage(err.to_string()).into(),
461        }
462    }
463}
464
465impl From<TryAcquireError> for Error {
466    fn from(err: TryAcquireError) -> Self {
467        Self {
468            kind: ErrorKind::ResourceExhausted,
469            error: ErrorMessage(err.to_string()).into(),
470        }
471    }
472}
473
474impl From<ToStrError> for Error {
475    fn from(err: ToStrError) -> Self {
476        Self::new(ErrorKind::FailedPrecondition, err)
477    }
478}
479
480impl From<Utf8Error> for Error {
481    fn from(err: Utf8Error) -> Self {
482        Self::new(ErrorKind::FailedPrecondition, err)
483    }
484}