Skip to main content

awc/client/
error.rs

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