1use crate::body::BoxBody;
8use crate::response::HttpResponse;
9use http::{HeaderMap, Response};
10use std::fmt;
11use std::fmt::Debug;
12use thiserror::Error;
13
14mod foreign_impls;
15pub(crate) mod macros;
16pub mod response_error;
17
18pub use response_error::ResponseError;
19
20#[derive(Debug, Error)]
21#[allow(missing_docs)]
22pub enum ServerError {
24 #[error(transparent)]
25 Io(#[from] std::io::Error),
26 #[error(transparent)]
27 Error(#[from] Error),
28 #[error(transparent)]
29 Http(#[from] http::Error),
30 #[error(transparent)]
31 ExtractionError(#[from] crate::extractors::ExtractionError),
32 #[error(transparent)]
33 ParseError(#[from] httparse::Error),
34 #[error(transparent)]
35 InvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
36 #[error(transparent)]
37 InvalidUri(#[from] http::uri::InvalidUri),
38 #[error(transparent)]
39 InvalidMethod(#[from] http::method::InvalidMethod),
40 #[error("Uri Empty")]
41 UriEmpty,
42 #[error("Method not Provided")]
43 MethodEmpty,
44 #[error("Version is not provided")]
45 VersionEmpty,
46 #[error("Connection was closed")]
47 ConnectionClosed,
48 #[error("Partially parsed the request")]
49 PartialParsed,
50 #[error("Invalid encoding for request")]
51 InvalidEncoding,
52 #[error("Failed to construct the service")]
53 ServiceConstructionFailed,
54}
55
56pub struct Error {
58 cause: Box<dyn ResponseError>,
59}
60
61impl Error {
68 pub fn as_response_error(&self) -> &dyn ResponseError {
70 self.cause.as_ref()
71 }
72
73 pub fn as_error<T: ResponseError + 'static>(&self) -> Option<&T> {
75 <dyn ResponseError>::downcast_ref(self.cause.as_ref())
76 }
77
78 pub fn error_response(&self) -> HttpResponse {
80 self.cause.error_response()
81 }
82}
83
84impl fmt::Display for Error {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 fmt::Display::fmt(&self.cause, f)
87 }
88}
89
90impl fmt::Debug for Error {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 write!(f, "{:?}", &self.cause)
93 }
94}
95
96impl std::error::Error for Error {
97 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
98 None
99 }
100}
101
102impl<T: ResponseError + 'static> From<T> for Error {
104 fn from(err: T) -> Error {
105 Error {
106 cause: Box::new(err),
107 }
108 }
109}
110
111impl From<Box<dyn ResponseError>> for Error {
112 fn from(value: Box<dyn ResponseError>) -> Self {
113 Error { cause: value }
114 }
115}
116
117impl From<Error> for Response<BoxBody> {
118 fn from(err: Error) -> Response<BoxBody> {
119 err.error_response().into()
120 }
121}
122
123impl From<HttpResponse> for Response<BoxBody> {
124 fn from(value: HttpResponse<BoxBody>) -> Self {
125 let mut response = Response::builder().status(value.status_code());
126
127 let headers = if let Some(headers) = response.headers_mut() {
128 headers
129 } else {
130 &mut HeaderMap::new()
131 };
132
133 for (header, value) in value.headers() {
134 headers.insert(header, value.clone());
135 }
136
137 response.body(value.body).unwrap()
138 }
139}