memcached/
error.rs

1use std::borrow::Cow;
2use std::error;
3use std::fmt;
4use std::io;
5use std::num;
6use std::str;
7use std::string;
8
9/// Client-side errors
10#[derive(Debug, PartialEq)]
11pub enum ClientError {
12    /// The key provided was longer than 250 bytes.
13    KeyTooLong,
14    /// The server returned an error prefixed with CLIENT_ERROR in response to a command.
15    Error(Cow<'static, str>),
16    ///connections is empty
17    ConnectionsIsEmpty,
18}
19
20impl fmt::Display for ClientError {
21    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22        match self {
23            ClientError::KeyTooLong => write!(f, "The provided key was too long."),
24            ClientError::ConnectionsIsEmpty => write!(f, "The Connections is empty."),
25            ClientError::Error(s) => write!(f, "{}", s),
26        }
27    }
28}
29
30impl From<ClientError> for MemcachedError {
31    fn from(err: ClientError) -> Self {
32        MemcachedError::ClientError(err)
33    }
34}
35
36/// Server-side errors
37#[derive(Debug)]
38pub enum ServerError {
39    /// When using binary protocol, the server returned magic byte other
40    /// than 0x81 in the response packet.
41    BadMagic(u8),
42    /// The client did not expect this response from the server.
43    BadResponse(Cow<'static, str>),
44    /// The server returned an error prefixed with SERVER_ERROR in response to a command.
45    Error(String),
46}
47
48impl fmt::Display for ServerError {
49    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
50        match self {
51            ServerError::BadMagic(e) => write!(
52                f,
53                "Expected 0x81 as magic in response header, but found: {:x}",
54                e
55            ),
56            ServerError::BadResponse(s) => write!(f, "Unexpected: {} in response", s),
57            ServerError::Error(s) => write!(f, "{}", s),
58        }
59    }
60}
61
62/// Command specific errors.
63#[derive(Debug, PartialEq, Copy, Clone)]
64pub enum CommandError {
65    /// The client tried to set a key which already existed in the server.
66    KeyExists,
67    /// The client tried to set a key which does not exist in the server.
68    KeyNotFound,
69    /// The value for a key was too large. The limit is usually 1MB.
70    ValueTooLarge,
71    /// Invalid arguments were passed to the command.
72    InvalidArguments,
73    /// The server requires authentication.
74    AuthenticationRequired,
75    ///Incr/Decr on non-numeric value.
76    IncrOrDecrOnNonNumericValue,
77    /// When using binary protocol, the server returned an unknown response status.
78    Unknown(u16),
79    /// The client sent an invalid command to the server.
80    InvalidCommand,
81}
82
83impl From<String> for ClientError {
84    fn from(s: String) -> Self {
85        ClientError::Error(Cow::Owned(s))
86    }
87}
88
89impl From<String> for ServerError {
90    fn from(s: String) -> Self {
91        ServerError::Error(s)
92    }
93}
94
95impl fmt::Display for CommandError {
96    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97        match self {
98            CommandError::KeyExists => write!(f, "Key already exists in the server."),
99            CommandError::KeyNotFound => write!(f, "Key was not found in the server."),
100            CommandError::ValueTooLarge => write!(f, "Value was too large."),
101            CommandError::InvalidArguments => write!(f, "Invalid arguments provided."),
102            CommandError::AuthenticationRequired => write!(f, "Authentication required."),
103            CommandError::IncrOrDecrOnNonNumericValue => {
104                write!(f, "Incr/Decr on non-numeric value.")
105            }
106            CommandError::Unknown(code) => write!(f, "Unknown error occurred with code: {}.", code),
107            CommandError::InvalidCommand => write!(f, "Invalid command sent to the server."),
108        }
109    }
110}
111
112impl From<u16> for CommandError {
113    fn from(status: u16) -> CommandError {
114        match status {
115            0x1 => CommandError::KeyNotFound,
116            0x2 => CommandError::KeyExists,
117            0x3 => CommandError::ValueTooLarge,
118            0x4 => CommandError::InvalidArguments,
119            0x6 => CommandError::IncrOrDecrOnNonNumericValue,
120            0x20 => CommandError::AuthenticationRequired,
121            e => CommandError::Unknown(e),
122        }
123    }
124}
125
126impl From<CommandError> for MemcachedError {
127    fn from(err: CommandError) -> Self {
128        MemcachedError::CommandError(err)
129    }
130}
131
132impl From<ServerError> for MemcachedError {
133    fn from(err: ServerError) -> Self {
134        MemcachedError::ServerError(err)
135    }
136}
137#[allow(missing_docs)]
138#[derive(Debug)]
139pub enum ParseError {
140    Bool(str::ParseBoolError),
141    Int(num::ParseIntError),
142    Float(num::ParseFloatError),
143    String(string::FromUtf8Error),
144    Str(std::str::Utf8Error),
145    Url(url::ParseError),
146    Bincode(bincode::Error),
147}
148
149impl error::Error for ParseError {
150    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
151        match self {
152            ParseError::Bool(ref e) => e.source(),
153            ParseError::Int(ref e) => e.source(),
154            ParseError::Float(ref e) => e.source(),
155            ParseError::String(ref e) => e.source(),
156            ParseError::Str(ref e) => e.source(),
157            ParseError::Url(ref e) => e.source(),
158            ParseError::Bincode(ref e) => e.source(),
159        }
160    }
161}
162
163impl fmt::Display for ParseError {
164    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
165        match self {
166            ParseError::Bool(ref e) => e.fmt(f),
167            ParseError::Int(ref e) => e.fmt(f),
168            ParseError::Float(ref e) => e.fmt(f),
169            ParseError::String(ref e) => e.fmt(f),
170            ParseError::Str(ref e) => e.fmt(f),
171            ParseError::Url(ref e) => e.fmt(f),
172            ParseError::Bincode(ref e) => e.fmt(f),
173        }
174    }
175}
176
177impl From<ParseError> for MemcachedError {
178    fn from(err: ParseError) -> Self {
179        MemcachedError::ParseError(err)
180    }
181}
182
183impl From<string::FromUtf8Error> for MemcachedError {
184    fn from(err: string::FromUtf8Error) -> MemcachedError {
185        ParseError::String(err).into()
186    }
187}
188
189impl From<std::str::Utf8Error> for MemcachedError {
190    fn from(err: std::str::Utf8Error) -> MemcachedError {
191        ParseError::Str(err).into()
192    }
193}
194
195impl From<num::ParseIntError> for MemcachedError {
196    fn from(err: num::ParseIntError) -> MemcachedError {
197        ParseError::Int(err).into()
198    }
199}
200
201impl From<num::ParseFloatError> for MemcachedError {
202    fn from(err: num::ParseFloatError) -> MemcachedError {
203        ParseError::Float(err).into()
204    }
205}
206
207impl From<url::ParseError> for MemcachedError {
208    fn from(err: url::ParseError) -> MemcachedError {
209        ParseError::Url(err).into()
210    }
211}
212
213impl From<str::ParseBoolError> for MemcachedError {
214    fn from(err: str::ParseBoolError) -> MemcachedError {
215        ParseError::Bool(err).into()
216    }
217}
218
219/// Stands for errors raised from rust-memcache
220#[derive(Debug)]
221pub enum MemcachedError {
222    /// Error raised when the provided memcache URL doesn't have a host name
223    #[cfg(feature = "tls")]
224    BadURL(String),
225    /// `std::io` related errors.
226    IOError(io::Error),
227    /// Client Errors
228    ClientError(ClientError),
229    /// Server Errors
230    ServerError(ServerError),
231    /// Command specific Errors
232    CommandError(CommandError),
233    #[cfg(feature = "tls")]
234    OpensslError(openssl::ssl::HandshakeError<std::net::TcpStream>),
235    /// Parse errors
236    ParseError(ParseError),
237    /// pool error
238    PoolError(&'static str),
239}
240
241impl fmt::Display for MemcachedError {
242    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
243        match *self {
244            #[cfg(feature = "tls")]
245            MemcachedError::BadURL(ref s) => s.fmt(f),
246            MemcachedError::IOError(ref err) => err.fmt(f),
247            #[cfg(feature = "tls")]
248            MemcachedError::OpensslError(ref err) => err.fmt(f),
249            MemcachedError::ParseError(ref err) => err.fmt(f),
250            MemcachedError::ClientError(ref err) => err.fmt(f),
251            MemcachedError::ServerError(ref err) => err.fmt(f),
252            MemcachedError::CommandError(ref err) => err.fmt(f),
253            MemcachedError::PoolError(ref err) => err.fmt(f),
254        }
255    }
256}
257
258impl error::Error for MemcachedError {
259    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
260        match *self {
261            #[cfg(feature = "tls")]
262            MemcachedError::BadURL(_) => None,
263            MemcachedError::IOError(ref err) => err.source(),
264            #[cfg(feature = "tls")]
265            MemcachedError::OpensslError(ref err) => err.source(),
266            MemcachedError::ParseError(ref p) => p.source(),
267            MemcachedError::ClientError(_)
268            | MemcachedError::ServerError(_)
269            | MemcachedError::CommandError(_)
270            | MemcachedError::PoolError(_) => None,
271        }
272    }
273}
274
275impl From<io::Error> for MemcachedError {
276    fn from(err: io::Error) -> MemcachedError {
277        MemcachedError::IOError(err)
278    }
279}
280
281impl<T> From<mobc::Error<T>> for MemcachedError {
282    fn from(_: mobc::Error<T>) -> MemcachedError {
283        MemcachedError::PoolError("mobc error")
284    }
285}
286
287impl From<bincode::Error> for MemcachedError {
288    fn from(e: bincode::Error) -> MemcachedError {
289        MemcachedError::ParseError(ParseError::Bincode(e))
290    }
291}
292
293#[cfg(feature = "tls")]
294impl From<openssl::error::ErrorStack> for MemcachedError {
295    fn from(err: openssl::error::ErrorStack) -> MemcachedError {
296        MemcachedError::OpensslError(openssl::ssl::HandshakeError::<std::net::TcpStream>::from(
297            err,
298        ))
299    }
300}
301
302#[cfg(feature = "tls")]
303impl From<openssl::ssl::HandshakeError<std::net::TcpStream>> for MemcachedError {
304    fn from(err: openssl::ssl::HandshakeError<std::net::TcpStream>) -> MemcachedError {
305        MemcachedError::OpensslError(err)
306    }
307}