1use std::fmt;
2
3use failure::{Backtrace, Context, Fail};
4
5#[derive(Eq, PartialEq, Debug, Fail)]
7pub enum ErrorKind {
8 #[fail(display = "failed to deserialize JSON")]
9 JsonDeserializationFailed,
10 #[fail(display = "failed to send request")]
11 FailedToSendRequest,
12 #[fail(display = "failed to read response")]
13 FailedToReadResponse,
14 #[fail(display = "failed to authenticate")]
15 AuthenticationFailed,
16 #[fail(display = "API call '{}' failed with code {} because {}", name, code, msg)]
17 ApiCallFailed {
18 name: &'static str,
19 code: isize,
20 msg: String,
21 },
22 #[fail(
23 display = "API call '{}' failed for unknown reason with status code {}",
24 name, status_code
25 )]
26 UnknownApiCallFailure { name: &'static str, status_code: u16 },
27}
28
29impl Clone for ErrorKind {
30 fn clone(&self) -> Self {
31 use self::ErrorKind::*;
32 match *self {
33 JsonDeserializationFailed => JsonDeserializationFailed,
34 FailedToSendRequest => FailedToSendRequest,
35 FailedToReadResponse => FailedToReadResponse,
36 AuthenticationFailed => AuthenticationFailed,
37 ApiCallFailed { name, code, ref msg } => ApiCallFailed {
38 name,
39 code,
40 msg: msg.clone(),
41 },
42 UnknownApiCallFailure { name, status_code } => UnknownApiCallFailure { name, status_code },
43 }
44 }
45}
46
47#[derive(Debug)]
49pub struct Error {
50 pub(crate) inner: Context<ErrorKind>,
51}
52
53impl Error {
54 pub fn kind(&self) -> &ErrorKind {
56 self.inner.get_context()
57 }
58}
59
60impl Clone for Error {
61 fn clone(&self) -> Self {
62 Error {
63 inner: Context::new(self.inner.get_context().clone()),
64 }
65 }
66}
67
68impl Fail for Error {
69 fn cause(&self) -> Option<&dyn Fail> {
70 self.inner.cause()
71 }
72
73 fn backtrace(&self) -> Option<&Backtrace> {
74 self.inner.backtrace()
75 }
76}
77
78impl fmt::Display for Error {
79 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80 fmt::Display::fmt(&self.inner, f)
81 }
82}
83
84impl From<ErrorKind> for Error {
85 fn from(kind: ErrorKind) -> Error {
86 Error {
87 inner: Context::new(kind),
88 }
89 }
90}
91
92impl From<Context<ErrorKind>> for Error {
93 fn from(inner: Context<ErrorKind>) -> Error {
94 Error { inner }
95 }
96}
97
98pub type Result<T> = ::std::result::Result<T, Error>;