tower_reqwest/
error.rs

1//! When something went wrong.
2
3/// Alias for a type-erased error type.
4pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
5
6/// This type represent all possible errors that can occurs during the request processing.
7#[derive(Debug, thiserror::Error)]
8pub enum Error {
9    /// An error occurred in the underlying client.
10    #[error("Client error: {0}")]
11    Client(#[from] ClientError),
12    /// An error occurred while processing a middleware.
13    #[error("Middleware error: {0}")]
14    Middleware(BoxError),
15}
16
17/// An error that can occur while handling HTTP requests.
18#[derive(Debug, thiserror::Error)]
19#[error("{inner}")]
20pub struct ClientError {
21    #[source]
22    inner: BoxError,
23    kind: ClientErrorKind,
24}
25
26impl ClientError {
27    /// Returns true if the error was caused by a timeout.
28    #[must_use]
29    pub fn is_timeout(&self) -> bool {
30        matches!(self.kind, ClientErrorKind::Timeout)
31    }
32
33    /// Returns true if the error is related to connect
34    #[must_use]
35    pub fn is_connection(&self) -> bool {
36        matches!(self.kind, ClientErrorKind::Timeout)
37    }
38
39    /// Returns true if the error is related to the request or response body.
40    #[must_use]
41    pub fn is_body(&self) -> bool {
42        matches!(self.kind, ClientErrorKind::Body)
43    }
44}
45
46#[derive(Debug, Clone, Copy)]
47enum ClientErrorKind {
48    Timeout,
49    Connection,
50    Body,
51    Other,
52}
53
54impl From<reqwest::Error> for ClientError {
55    fn from(value: reqwest::Error) -> Self {
56        let kind = if value.is_timeout() {
57            ClientErrorKind::Timeout
58        } else if value.is_connect() {
59            ClientErrorKind::Connection
60        } else if value.is_body() {
61            ClientErrorKind::Body
62        } else {
63            ClientErrorKind::Other
64        };
65
66        Self {
67            inner: Box::new(value),
68            kind,
69        }
70    }
71}
72
73impl From<reqwest::Error> for Error {
74    fn from(value: reqwest::Error) -> Self {
75        Self::Client(value.into())
76    }
77}