1use std::{error::Error, fmt, io, str::Utf8Error};
3
4use serde::de::value::Error as DeError;
5use serde_json::error::Error as JsonError;
6use serde_urlencoded::ser::Error as FormError;
7
8use crate::client;
9use crate::http::{self, StatusCode, header};
10use crate::util::timeout::TimeoutError;
11#[cfg(feature = "ws")]
12use crate::ws::error::HandshakeError;
13
14use super::{HttpResponse, WebResponseError, error};
15
16#[derive(Debug, thiserror::Error)]
26#[error("Default error marker")]
27pub struct DefaultError {
28 _ph: io::Error,
29}
30
31impl<St> WebResponseError<St, DefaultError> for DefaultError {
32 fn error_response(&self, _: &St) -> HttpResponse {
33 unreachable!()
34 }
35}
36
37impl<St> WebResponseError<St, DefaultError> for JsonError {
44 fn error_response(&self, _: &St) -> HttpResponse {
45 HttpResponse::render_with(StatusCode::INTERNAL_SERVER_ERROR, self)
46 }
47}
48
49impl<St> WebResponseError<St, DefaultError> for FormError {
54 fn error_response(&self, _: &St) -> HttpResponse {
55 HttpResponse::render_with(StatusCode::INTERNAL_SERVER_ERROR, self)
56 }
57}
58
59#[cfg(feature = "openssl")]
60impl<St> WebResponseError<St, DefaultError> for tls_openssl::ssl::Error {
62 fn error_response(&self, _: &St) -> HttpResponse {
63 HttpResponse::render_with(StatusCode::BAD_REQUEST, self)
64 }
65}
66
67#[cfg(feature = "openssl")]
68impl<St, T: fmt::Debug + 'static> WebResponseError<St, DefaultError>
70 for tls_openssl::ssl::HandshakeError<T>
71{
72}
73
74impl<St> WebResponseError<St, DefaultError> for DeError {
76 fn error_response(&self, _: &St) -> HttpResponse {
77 HttpResponse::render_with(StatusCode::BAD_REQUEST, self)
78 }
79}
80
81impl<St> WebResponseError<St, DefaultError> for crate::http::error::Canceled {
83 fn error_response(&self, _: &St) -> HttpResponse {
84 HttpResponse::render_with(StatusCode::INTERNAL_SERVER_ERROR, self)
85 }
86}
87
88impl<St, E: Error + 'static> WebResponseError<St, DefaultError>
90 for crate::http::error::BlockingError<E>
91{
92 fn error_response(&self, _: &St) -> HttpResponse {
93 HttpResponse::render_with(StatusCode::INTERNAL_SERVER_ERROR, self)
94 }
95}
96
97impl<St> WebResponseError<St, DefaultError> for Utf8Error {
99 fn error_response(&self, _: &St) -> HttpResponse {
100 HttpResponse::render_with(StatusCode::BAD_REQUEST, self)
101 }
102}
103
104impl<St> WebResponseError<St, DefaultError> for crate::http::error::HttpError {
107 fn error_response(&self, _: &St) -> HttpResponse {
108 HttpResponse::render_with(StatusCode::INTERNAL_SERVER_ERROR, self)
109 }
110}
111
112impl<St> WebResponseError<St, DefaultError> for io::Error {
114 fn error_response(&self, _: &St) -> HttpResponse {
115 let status = match self.kind() {
116 io::ErrorKind::NotFound => StatusCode::NOT_FOUND,
117 io::ErrorKind::PermissionDenied => StatusCode::FORBIDDEN,
118 _ => StatusCode::INTERNAL_SERVER_ERROR,
119 };
120 HttpResponse::render_with(status, self)
121 }
122}
123
124impl<St> WebResponseError<St, DefaultError> for error::UrlGenerationError {
126 fn error_response(&self, _: &St) -> HttpResponse {
127 HttpResponse::render_with(StatusCode::INTERNAL_SERVER_ERROR, self)
128 }
129}
130
131impl<St> WebResponseError<St, DefaultError> for error::UrlencodedError {
133 fn error_response(&self, _: &St) -> HttpResponse {
134 let status = match self {
135 error::UrlencodedError::Overflow { .. } => StatusCode::PAYLOAD_TOO_LARGE,
136 error::UrlencodedError::UnknownLength => StatusCode::LENGTH_REQUIRED,
137 _ => StatusCode::BAD_REQUEST,
138 };
139 HttpResponse::render_with(status, self)
140 }
141}
142
143impl<St> WebResponseError<St, DefaultError> for error::JsonPayloadError {
147 fn error_response(&self, _: &St) -> HttpResponse {
148 let status = match self {
149 error::JsonPayloadError::Overflow => StatusCode::PAYLOAD_TOO_LARGE,
150 _ => StatusCode::BAD_REQUEST,
151 };
152 HttpResponse::render_with(status, self)
153 }
154}
155
156impl<St> WebResponseError<St, DefaultError> for error::PathError {
158 fn error_response(&self, _: &St) -> HttpResponse {
159 HttpResponse::render_with(StatusCode::NOT_FOUND, self)
160 }
161}
162
163impl<St> WebResponseError<St, DefaultError> for error::QueryPayloadError {
165 fn error_response(&self, _: &St) -> HttpResponse {
166 HttpResponse::render_with(StatusCode::BAD_REQUEST, self)
167 }
168}
169
170impl<St> WebResponseError<St, DefaultError> for error::PayloadError {
171 fn error_response(&self, _: &St) -> HttpResponse {
172 HttpResponse::render_with(StatusCode::BAD_REQUEST, self)
173 }
174}
175
176impl<St> WebResponseError<St, DefaultError> for http::error::PayloadError {
181 fn error_response(&self, _: &St) -> HttpResponse {
182 let status = match self {
183 http::error::PayloadError::Overflow => StatusCode::PAYLOAD_TOO_LARGE,
184 _ => StatusCode::BAD_REQUEST,
185 };
186 HttpResponse::render_with(status, self)
187 }
188}
189
190#[cfg(feature = "cookie")]
191impl<St> WebResponseError<St, DefaultError> for coo_kie::ParseError {
193 fn error_response(&self, _: &St) -> HttpResponse {
194 HttpResponse::render_with(StatusCode::BAD_REQUEST, self)
195 }
196}
197
198impl<St> WebResponseError<St, DefaultError> for http::error::ContentTypeError {
200 fn error_response(&self, _: &St) -> HttpResponse {
201 HttpResponse::render_with(StatusCode::BAD_REQUEST, self)
202 }
203}
204
205impl<St> WebResponseError<St, DefaultError> for client::error::ClientError {
207 fn error_response(&self, _: &St) -> HttpResponse {
208 let status = match &self {
209 client::error::ClientError::Connect(_) => StatusCode::BAD_REQUEST,
210 client::error::ClientError::Timeout => StatusCode::GATEWAY_TIMEOUT,
211 _ => StatusCode::INTERNAL_SERVER_ERROR,
212 };
213
214 HttpResponse::render_with(status, self)
215 }
216}
217
218impl<St> WebResponseError<St, DefaultError> for client::error::ClientPayloadError {
220 fn error_response(&self, _: &St) -> HttpResponse {
221 HttpResponse::render_with(StatusCode::BAD_REQUEST, self)
222 }
223}
224
225#[cfg(feature = "ws")]
226impl<St> WebResponseError<St, DefaultError> for HandshakeError {
228 fn error_response(&self, _: &St) -> HttpResponse {
229 match self {
230 HandshakeError::GetMethodRequired => HttpResponse::MethodNotAllowed()
231 .header(header::ALLOW, "GET")
232 .build(),
233 HandshakeError::NoWebsocketUpgrade => HttpResponse::BadRequest()
234 .reason("No WebSocket UPGRADE header found")
235 .build(),
236 HandshakeError::NoConnectionUpgrade => HttpResponse::BadRequest()
237 .reason("No CONNECTION upgrade")
238 .build(),
239 HandshakeError::NoVersionHeader => HttpResponse::BadRequest()
240 .reason("Websocket version header is required")
241 .header(header::SEC_WEBSOCKET_VERSION, "13")
242 .build(),
243 HandshakeError::UnsupportedVersion => HttpResponse::BadRequest()
244 .reason("Unsupported version")
245 .header(header::SEC_WEBSOCKET_VERSION, "13")
246 .build(),
247 HandshakeError::BadWebsocketKey => {
248 HttpResponse::BadRequest().reason("Handshake error").build()
249 }
250 HandshakeError::BadWebsocketProtocol => HttpResponse::BadRequest()
251 .reason("Invalid websocket subprotocol")
252 .build(),
253 }
254 }
255}
256
257impl<St, E> WebResponseError<St, DefaultError> for TimeoutError<E>
259where
260 E: fmt::Display + fmt::Debug + WebResponseError<St, DefaultError> + 'static,
261{
262 fn error_response(&self, st: &St) -> HttpResponse {
263 match self {
264 TimeoutError::Service(e) => e.error_response(st),
265 TimeoutError::Timeout => WebResponseError::<St, DefaultError>::error_response(
266 &super::error::ErrorGatewayTimeout(""),
267 st,
268 ),
269 }
270 }
271}