• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 //! Definition of `HttpClientErrors` which includes errors that may occur in
15 //! this crate.
16 
17 use core::fmt::{Debug, Display, Formatter};
18 use std::error::Error;
19 
20 /// The structure encapsulates errors that can be encountered when working with
21 /// the HTTP client.
22 pub struct HttpClientError {
23     kind: ErrorKind,
24     cause: Option<Box<dyn Error + Send + Sync>>,
25 }
26 
27 impl HttpClientError {
28     /// Creates a `UserAborted` error.
29     ///
30     /// # Examples
31     ///
32     /// ```
33     /// # use ylong_http_client::HttpClientError;
34     ///
35     /// let user_aborted = HttpClientError::user_aborted();
36     /// ```
user_aborted() -> Self37     pub fn user_aborted() -> Self {
38         Self {
39             kind: ErrorKind::UserAborted,
40             cause: None,
41         }
42     }
43 
44     /// Creates an `Other` error.
45     ///
46     /// # Examples
47     ///
48     /// ```
49     /// # use ylong_http_client::HttpClientError;
50     ///
51     /// # fn error(error: std::io::Error) {
52     /// let other = HttpClientError::other(Some(error));
53     /// # }
54     /// ```
other<T: Into<Box<dyn Error + Send + Sync>>>(cause: Option<T>) -> Self55     pub fn other<T: Into<Box<dyn Error + Send + Sync>>>(cause: Option<T>) -> Self {
56         Self {
57             kind: ErrorKind::Other,
58             cause: cause.map(|e| e.into()),
59         }
60     }
61 
62     /// Gets the `ErrorKind` of this `HttpClientError`.
63     ///
64     /// # Examples
65     ///
66     /// ```
67     /// # use ylong_http_client::{ErrorKind, HttpClientError};
68     ///
69     /// let user_aborted = HttpClientError::user_aborted();
70     /// assert_eq!(user_aborted.error_kind(), ErrorKind::UserAborted);
71     /// ```
error_kind(&self) -> ErrorKind72     pub fn error_kind(&self) -> ErrorKind {
73         self.kind
74     }
75 
new_with_cause<T>(kind: ErrorKind, cause: Option<T>) -> Self where T: Into<Box<dyn Error + Send + Sync>>,76     pub(crate) fn new_with_cause<T>(kind: ErrorKind, cause: Option<T>) -> Self
77     where
78         T: Into<Box<dyn Error + Send + Sync>>,
79     {
80         Self {
81             kind,
82             cause: cause.map(|e| e.into()),
83         }
84     }
85 
new_with_message(kind: ErrorKind, message: &str) -> Self86     pub(crate) fn new_with_message(kind: ErrorKind, message: &str) -> Self {
87         Self {
88             kind,
89             cause: Some(CauseMessage::new(message).into()),
90         }
91     }
92 }
93 
94 impl Debug for HttpClientError {
fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result95     fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
96         let mut builder = f.debug_struct("HttpClientError");
97         builder.field("ErrorKind", &self.kind);
98         if let Some(ref cause) = self.cause {
99             builder.field("Cause", cause);
100         }
101         builder.finish()
102     }
103 }
104 
105 impl Display for HttpClientError {
fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result106     fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
107         f.write_str(self.kind.as_str())?;
108 
109         if let Some(ref cause) = self.cause {
110             write!(f, ": {cause}")?;
111         }
112         Ok(())
113     }
114 }
115 
116 impl Error for HttpClientError {}
117 
118 /// Error kinds which can indicate the type of a `HttpClientError`.
119 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
120 pub enum ErrorKind {
121     /// Errors for decoding response body.
122     BodyDecode,
123 
124     /// Errors for transferring request body or response body.
125     BodyTransfer,
126 
127     /// Errors for using various builder.
128     Build,
129 
130     /// Errors for connecting to a server.
131     Connect,
132 
133     /// Errors for upgrading a connection.
134     ConnectionUpgrade,
135 
136     /// Other error kinds.
137     Other,
138 
139     /// Errors for following redirect.
140     Redirect,
141 
142     /// Errors for sending a request.
143     Request,
144 
145     /// Errors for reaching a timeout.
146     Timeout,
147 
148     /// User raised errors.
149     UserAborted,
150 }
151 
152 impl ErrorKind {
153     /// Gets the string info of this `ErrorKind`.
154     ///
155     /// # Examples
156     ///
157     /// ```
158     /// use ylong_http_client::ErrorKind;
159     ///
160     /// assert_eq!(ErrorKind::UserAborted.as_str(), "User Aborted Error");
161     /// ```
as_str(&self) -> &'static str162     pub fn as_str(&self) -> &'static str {
163         match self {
164             Self::BodyDecode => "Body Decode Error",
165             Self::BodyTransfer => "Body Transfer Error",
166             Self::Build => "Build Error",
167             Self::Connect => "Connect Error",
168             Self::ConnectionUpgrade => "Connection Upgrade Error",
169             Self::Other => "Other Error",
170             Self::Redirect => "Redirect Error",
171             Self::Request => "Request Error",
172             Self::Timeout => "Timeout Error",
173             Self::UserAborted => "User Aborted Error",
174         }
175     }
176 }
177 
178 /// Messages for summarizing the cause of the error
179 pub(crate) struct CauseMessage(String);
180 
181 impl CauseMessage {
new(message: &str) -> Self182     pub(crate) fn new(message: &str) -> Self {
183         Self(message.to_string())
184     }
185 }
186 
187 impl Debug for CauseMessage {
fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result188     fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
189         f.write_str(self.0.as_str())
190     }
191 }
192 
193 impl Display for CauseMessage {
fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result194     fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
195         f.write_str(self.0.as_str())
196     }
197 }
198 
199 impl Error for CauseMessage {}
200