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
use std::error;
use std::fmt::{self, Display};
use std::io;
use std::result;

#[derive(Debug)]
/// Common errors that can occur during HTTP requests.
pub enum Error {
    /// IO Error
    Io(io::Error),
    /// Error generated by the `http` crate.
    Http(http::Error),
    /// TLS error encountered while connecting to an https server.
    #[cfg(feature = "tls")]
    Tls(native_tls::Error),
    /// Invalid URL ecountered while processing the request or response.
    InvalidUrl(&'static str),
    /// Server sent an invalid response.
    InvalidResponse(&'static str),
    /// Decoding error happened while trying to decode text.
    DecodingError(&'static str),
    /// Other errors.
    Other(&'static str),
    /// JSON decoding/encoding error.
    #[cfg(feature = "json")]
    Json(serde_json::Error),
}

impl Display for Error {
    fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Error::Io(e) => write!(w, "Io({})", e),
            Error::Http(e) => write!(w, "Http({})", e),
            #[cfg(feature = "tls")]
            Error::Tls(e) => write!(w, "Tls({})", e),
            Error::InvalidUrl(s) => write!(w, "InvalidUrl({})", s),
            Error::InvalidResponse(s) => write!(w, "InvalidResponse({})", s),
            Error::DecodingError(s) => write!(w, "DecodingError({})", s),
            Error::Other(s) => write!(w, "Other({}", s),
            #[cfg(feature = "json")]
            Error::Json(e) => write!(w, "JsonError({})", e),
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match self {
            Error::Io(e) => e.description(),
            Error::Http(e) => e.description(),
            #[cfg(feature = "tls")]
            Error::Tls(e) => e.description(),
            Error::InvalidUrl(s) => s,
            Error::InvalidResponse(s) => s,
            Error::DecodingError(s) => s,
            Error::Other(s) => s,
            #[cfg(feature = "json")]
            Error::Json(e) => e.description(),
        }
    }

    fn cause(&self) -> Option<&dyn error::Error> {
        match self {
            Error::Io(e) => Some(e),
            Error::Http(e) => Some(e),
            #[cfg(feature = "tls")]
            Error::Tls(e) => Some(e),
            #[cfg(feature = "json")]
            Error::Json(e) => Some(e),
            _ => None,
        }
    }
}

macro_rules! impl_from {
    ($t:ty, $i:ident) => {
        impl From<$t> for Error {
            fn from(err: $t) -> Error {
                Error::$i(err)
            }
        }
    };
}

impl_from!(io::Error, Io);
impl_from!(http::Error, Http);
#[cfg(feature = "tls")]
impl_from!(native_tls::Error, Tls);
#[cfg(feature = "json")]
impl_from!(serde_json::Error, Json);

/// Wrapper for the `Result` type with an `Error`.
pub type Result<T = ()> = result::Result<T, Error>;