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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
use std::convert::From;
use std::error::Error as StdError;
use std::fmt::{Display, Error as FmtError, Formatter};
use hyper::Error as HttpError;
use hyper::error::UriError;
#[cfg(feature = "tls")]
use native_tls::Error as TlsError;
use serde_json::Error as SerializationError;
use tokio_timer::TimeoutError as TokioTimeoutError;
use url::ParseError as UrlError;
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq)]
pub struct ApiError {
pub cause: Option<String>,
#[serde(rename = "errorCode")]
pub error_code: u64,
pub index: u64,
pub message: String,
}
impl Display for ApiError {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
write!(f, "{}", self.message)
}
}
impl StdError for ApiError {
fn description(&self) -> &str {
&self.message
}
}
#[derive(Debug)]
pub enum Error {
Api(ApiError),
Http(HttpError),
InvalidConditions,
InvalidUri(UriError),
InvalidUrl(UrlError),
NoEndpoints,
Serialization(SerializationError),
#[cfg(feature = "tls")]
Tls(TlsError),
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
match *self {
Error::Api(ref error) => write!(f, "{}", error),
Error::Http(ref error) => write!(f, "{}", error),
ref error @ Error::InvalidConditions => write!(f, "{}", error.description()),
Error::InvalidUri(ref error) => write!(f, "{}", error),
Error::InvalidUrl(ref error) => write!(f, "{}", error),
ref error @ Error::NoEndpoints => write!(f, "{}", error.description()),
#[cfg(feature = "tls")]
Error::Tls(ref error) => write!(f, "{}", error),
Error::Serialization(ref error) => write!(f, "{}", error),
}
}
}
impl StdError for Error {
fn description(&self) -> &str {
match *self {
Error::Api(_) => "the etcd server returned an error",
Error::Http(_) => "an error occurred during the HTTP request",
Error::InvalidConditions => "current value or modified index is required",
Error::InvalidUri(_) => "a supplied endpoint could not be parsed as a URI",
Error::InvalidUrl(_) => "a URL for the request could not be generated",
Error::NoEndpoints => "at least one endpoint is required to create a Client",
#[cfg(feature = "tls")]
Error::Tls(_) => "an error occurred configuring TLS",
Error::Serialization(_) => "an error occurred deserializing JSON",
}
}
}
impl From<HttpError> for Error {
fn from(error: HttpError) -> Error {
Error::Http(error)
}
}
#[cfg(feature = "tls")]
impl From<TlsError> for Error {
fn from(error: TlsError) -> Error {
Error::Tls(error)
}
}
impl From<UrlError> for Error {
fn from(error: UrlError) -> Error {
Error::InvalidUrl(error)
}
}
impl From<SerializationError> for Error {
fn from(error: SerializationError) -> Error {
Error::Serialization(error)
}
}
impl From<UriError> for Error {
fn from(error: UriError) -> Error {
Error::InvalidUri(error)
}
}
#[derive(Debug)]
pub enum WatchError {
Other(Vec<Error>),
Timeout,
}
impl<T> From<TokioTimeoutError<T>> for WatchError {
fn from(_: TokioTimeoutError<T>) -> Self {
WatchError::Timeout
}
}
impl Display for WatchError {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
match *self {
WatchError::Timeout => write!(f, "{}", self.description()),
ref other => other.fmt(f),
}
}
}
impl StdError for WatchError {
fn description(&self) -> &str {
"operation timed out"
}
}