awaur/endpoints/
errors.rs

1/// Error type used if an API request recieved a successful response, but the
2/// body bytes failed to deserialize into the expected strong-type. This
3/// contains the original bytes that failed to deserialize, for debugging
4/// purposes.
5#[derive(Debug, thiserror::Error)]
6#[error("failed to deserialize a response from:\n{uri}\n{inner}")]
7pub struct DeserializeError {
8    uri: url::Url,
9    bytes: Vec<u8>,
10    #[source]
11    inner: serde_path_to_error::Error<serde_json::Error>,
12}
13
14/// A request to a URI that was expected to return successfully with 200
15/// OK has failed to do so. This contains the status code that was received
16/// instead, and the bytes in the body of the response.
17#[derive(Debug, thiserror::Error)]
18#[error("received unsuccessful status code {status} from:\n{uri}")]
19pub struct ResponseError {
20    uri: url::Url,
21    bytes: Vec<u8>,
22    status: http::StatusCode,
23}
24
25macro_rules! impl_field_accessors {
26    ($implementor:ident) => {
27        impl $implementor {
28            /// Reference to the URI of the request.
29            pub fn uri(&self) -> &url::Url {
30                &self.uri
31            }
32
33            /// Reference to the body bytes of the response.
34            pub fn bytes(&self) -> &[u8] {
35                &self.bytes
36            }
37
38            /// Consume this error, taking out the URI of the request.
39            pub fn into_uri(self) -> url::Url {
40                self.uri
41            }
42
43            /// Consume this error, taking out the body bytes of the response.
44            pub fn into_bytes(self) -> Vec<u8> {
45                self.bytes
46            }
47
48            /// Consume this error, taking out both the URI of the request,
49            /// and the body bytes of the response.
50            pub fn into_uri_bytes(self) -> (url::Url, Vec<u8>) {
51                (self.uri, self.bytes)
52            }
53        }
54    };
55}
56
57impl_field_accessors!(DeserializeError);
58impl_field_accessors!(ResponseError);
59
60impl DeserializeError {
61    #[doc(hidden)]
62    pub fn __new(
63        uri: url::Url,
64        bytes: Vec<u8>,
65        error: serde_path_to_error::Error<serde_json::Error>,
66    ) -> Self {
67        Self {
68            uri,
69            bytes,
70            inner: error,
71        }
72    }
73
74    /// Reference to the [`Path`] of the value that failed to deserialize.
75    ///
76    /// [`Path`]: serde_path_to_error::Path
77    pub fn path(&self) -> &serde_path_to_error::Path {
78        self.inner.path()
79    }
80
81    /// Reference to the original [`serde_json::Error`].
82    pub fn inner(&self) -> &serde_json::Error {
83        self.inner.inner()
84    }
85
86    /// Consume this error, taking out the original [`serde_json::Error`].
87    pub fn into_inner(self) -> serde_json::Error {
88        self.inner.into_inner()
89    }
90}
91
92impl ResponseError {
93    #[doc(hidden)]
94    pub fn __new(uri: url::Url, bytes: Vec<u8>, status: http::StatusCode) -> Self {
95        Self { uri, bytes, status }
96    }
97
98    /// Copy of the response's status code.
99    pub fn status_code(&self) -> http::StatusCode {
100        self.status
101    }
102}