selectel_mks/
error.rs

1/// MKS error return type.
2#[derive(Debug)]
3pub enum Error {
4    /// Failed to deserialize response body.
5    DeserializeError(serde_json::Error, String),
6
7    /// Failed to serialize a struct into request body.
8    SerializeError(serde_json::Error),
9
10    /// Bad endpoint value.
11    EndpointError,
12
13    /// Empty token value.
14    EmptyTokenError,
15
16    /// HTTP response contains bad status code.
17    HttpError(u16, String),
18
19    /// Failed to perform HTTP request with Hyper.
20    HyperError(hyper::Error),
21
22    /// Error while building a new request.
23    RequestError,
24
25    /// Request timed out.
26    TimeoutError,
27
28    /// Bad URL for a new request.
29    UrlError,
30}
31
32impl std::fmt::Display for Error {
33    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34        match &*self {
35            Error::DeserializeError(err, body) => {
36                format!("Failed to deserialize body: {}, error: {}", err, body).fmt(f)
37            }
38            Error::SerializeError(err) => {
39                format!("Failed to serialize a struct, error: {}", err).fmt(f)
40            }
41            Error::EndpointError => "Failed to parse base endpoint URL".fmt(f),
42            Error::EmptyTokenError => "Token cannot be empty".fmt(f),
43            Error::HttpError(status, err) => {
44                format!("Bad status code: {}, error body: {}", status, err).fmt(f)
45            }
46            Error::HyperError(err) => {
47                format!("Failed to make the request due to Hyper error: {}", err).fmt(f)
48            }
49            Error::RequestError => "Failed to build a new request".fmt(f),
50            Error::TimeoutError => "Request timed out".fmt(f),
51            Error::UrlError => "Failed to parse URL for request".fmt(f),
52        }
53    }
54}
55
56impl std::error::Error for Error {}
57
58impl std::convert::From<hyper::Error> for Error {
59    fn from(e: hyper::Error) -> Self {
60        Error::HyperError(e)
61    }
62}
63
64impl std::convert::From<tokio::time::Elapsed> for Error {
65    fn from(_e: tokio::time::Elapsed) -> Self {
66        Error::TimeoutError
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[test]
75    fn impl_error() {
76        #[derive(Debug)]
77        struct B(Option<Box<dyn std::error::Error + 'static>>);
78
79        impl std::fmt::Display for B {
80            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81                write!(f, "B")
82            }
83        }
84
85        impl std::error::Error for B {}
86
87        let err = B(Some(Box::new(Error::RequestError)));
88
89        let _err = &err as &(dyn std::error::Error);
90    }
91}