actori_http/client/
error.rs

1use std::io;
2
3use actori_connect::resolver::ResolveError;
4use derive_more::{Display, From};
5
6#[cfg(feature = "openssl")]
7use actori_connect::ssl::openssl::{HandshakeError, SslError};
8
9use crate::error::{Error, ParseError, ResponseError};
10use crate::http::{Error as HttpError, StatusCode};
11
12/// A set of errors that can occur while connecting to an HTTP host
13#[derive(Debug, Display, From)]
14pub enum ConnectError {
15    /// SSL feature is not enabled
16    #[display(fmt = "SSL is not supported")]
17    SslIsNotSupported,
18
19    /// SSL error
20    #[cfg(feature = "openssl")]
21    #[display(fmt = "{}", _0)]
22    SslError(SslError),
23
24    /// SSL Handshake error
25    #[cfg(feature = "openssl")]
26    #[display(fmt = "{}", _0)]
27    SslHandshakeError(String),
28
29    /// Failed to resolve the hostname
30    #[display(fmt = "Failed resolving hostname: {}", _0)]
31    Resolver(ResolveError),
32
33    /// No dns records
34    #[display(fmt = "No dns records found for the input")]
35    NoRecords,
36
37    /// Http2 error
38    #[display(fmt = "{}", _0)]
39    H2(h2::Error),
40
41    /// Connecting took too long
42    #[display(fmt = "Timeout out while establishing connection")]
43    Timeout,
44
45    /// Connector has been disconnected
46    #[display(fmt = "Internal error: connector has been disconnected")]
47    Disconnected,
48
49    /// Unresolved host name
50    #[display(fmt = "Connector received `Connect` method with unresolved host")]
51    Unresolverd,
52
53    /// Connection io error
54    #[display(fmt = "{}", _0)]
55    Io(io::Error),
56}
57
58impl From<actori_connect::ConnectError> for ConnectError {
59    fn from(err: actori_connect::ConnectError) -> ConnectError {
60        match err {
61            actori_connect::ConnectError::Resolver(e) => ConnectError::Resolver(e),
62            actori_connect::ConnectError::NoRecords => ConnectError::NoRecords,
63            actori_connect::ConnectError::InvalidInput => panic!(),
64            actori_connect::ConnectError::Unresolverd => ConnectError::Unresolverd,
65            actori_connect::ConnectError::Io(e) => ConnectError::Io(e),
66        }
67    }
68}
69
70#[cfg(feature = "openssl")]
71impl<T: std::fmt::Debug> From<HandshakeError<T>> for ConnectError {
72    fn from(err: HandshakeError<T>) -> ConnectError {
73        ConnectError::SslHandshakeError(format!("{:?}", err))
74    }
75}
76
77#[derive(Debug, Display, From)]
78pub enum InvalidUrl {
79    #[display(fmt = "Missing url scheme")]
80    MissingScheme,
81    #[display(fmt = "Unknown url scheme")]
82    UnknownScheme,
83    #[display(fmt = "Missing host name")]
84    MissingHost,
85    #[display(fmt = "Url parse error: {}", _0)]
86    HttpError(http::Error),
87}
88
89/// A set of errors that can occur during request sending and response reading
90#[derive(Debug, Display, From)]
91pub enum SendRequestError {
92    /// Invalid URL
93    #[display(fmt = "Invalid URL: {}", _0)]
94    Url(InvalidUrl),
95    /// Failed to connect to host
96    #[display(fmt = "Failed to connect to host: {}", _0)]
97    Connect(ConnectError),
98    /// Error sending request
99    Send(io::Error),
100    /// Error parsing response
101    Response(ParseError),
102    /// Http error
103    #[display(fmt = "{}", _0)]
104    Http(HttpError),
105    /// Http2 error
106    #[display(fmt = "{}", _0)]
107    H2(h2::Error),
108    /// Response took too long
109    #[display(fmt = "Timeout out while waiting for response")]
110    Timeout,
111    /// Tunnels are not supported for http2 connection
112    #[display(fmt = "Tunnels are not supported for http2 connection")]
113    TunnelNotSupported,
114    /// Error sending request body
115    Body(Error),
116}
117
118/// Convert `SendRequestError` to a server `Response`
119impl ResponseError for SendRequestError {
120    fn status_code(&self) -> StatusCode {
121        match *self {
122            SendRequestError::Connect(ConnectError::Timeout) => {
123                StatusCode::GATEWAY_TIMEOUT
124            }
125            SendRequestError::Connect(_) => StatusCode::BAD_REQUEST,
126            _ => StatusCode::INTERNAL_SERVER_ERROR,
127        }
128    }
129}
130
131/// A set of errors that can occur during freezing a request
132#[derive(Debug, Display, From)]
133pub enum FreezeRequestError {
134    /// Invalid URL
135    #[display(fmt = "Invalid URL: {}", _0)]
136    Url(InvalidUrl),
137    /// Http error
138    #[display(fmt = "{}", _0)]
139    Http(HttpError),
140}
141
142impl From<FreezeRequestError> for SendRequestError {
143    fn from(e: FreezeRequestError) -> Self {
144        match e {
145            FreezeRequestError::Url(e) => e.into(),
146            FreezeRequestError::Http(e) => e.into(),
147        }
148    }
149}