1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use std::io;
use ws;
use ring;
#[cfg(feature = "media")]
use reqwest;
use json;
use base64;
use protobuf;
macro_rules! impl_from_for_error {
($error:ident, $($var:ident => $orig:ty),*) => {
$(
impl From<$orig> for $error {
fn from(err: $orig) -> $error {
$error::$var(err)
}
}
)*
}
}
#[macro_export]
macro_rules! bail_untyped {
($msg:expr) => {
return Err(WaError::Untyped($msg.into()));
};
($($arg:tt)*) => {
return Err(WaError::UntypedOwned(format!($($arg)*)));
}
}
pub trait WaErrorContext {
fn with_context(self, ctx: &'static str) -> Self;
fn with_owned_context<T: Into<String>>(self, ctx: T) -> Self;
}
impl<T> WaErrorContext for Result<T> {
fn with_context(self, ctx: &'static str) -> Self {
self.map_err(|e| {
WaError::Context(ctx, Box::new(e))
})
}
fn with_owned_context<U: Into<String>>(self, ctx: U) -> Self {
self.map_err(|e| {
WaError::OwnedContext(ctx.into(), Box::new(e))
})
}
}
#[derive(Debug, Fail)]
pub enum WaError {
#[fail(display = "I/O error: {}", _0)]
Io(io::Error),
#[fail(display = "WebSocket error: {}", _0)]
Websocket(ws::Error),
#[fail(display = "Crypto error: {}", _0)]
Crypto(ring::error::Unspecified),
#[cfg(feature = "media")]
#[fail(display = "reqwest error: {}", _0)]
Reqwest(reqwest::Error),
#[fail(display = "JSON error: {}", _0)]
Json(json::Error),
#[fail(display = "base64 decode error: {}", _0)]
Base64(base64::DecodeError),
#[fail(display = "Protobuf error: {}", _0)]
Protobuf(protobuf::ProtobufError),
#[fail(display = "Missing node attribute \"{}\"", _0)]
NodeAttributeMissing(&'static str),
#[fail(display = "Missing JSON field \"{}\"", _0)]
JsonFieldMissing(&'static str),
#[fail(display = "while {}: {}", _0, _1)]
Context(&'static str, Box<WaError>),
#[fail(display = "while {}: {}", _0, _1)]
OwnedContext(String, Box<WaError>),
#[fail(display = "unknown tag {}", _0)]
InvalidTag(u8),
#[fail(display = "{}", _0)]
UntypedOwned(String),
#[fail(display = "{}", _0)]
Untyped(&'static str)
}
pub type WaResult<T> = ::std::result::Result<T, WaError>;
pub(crate) type Result<T> = WaResult<T>;
impl_from_for_error!(WaError,
Io => io::Error,
Websocket => ws::Error,
Crypto => ring::error::Unspecified,
Json => json::Error,
Base64 => base64::DecodeError,
Protobuf => protobuf::ProtobufError,
UntypedOwned => String,
Untyped => &'static str);
#[cfg(feature = "media")]
impl_from_for_error!(WaError,
Reqwest => reqwest::Error);