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}