1use std::{cell::RefCell, fmt, io::Write, marker::PhantomData};
3
4pub use ntex_http::error::Error as HttpError;
5pub use serde_json::error::Error as JsonError;
6#[cfg(feature = "url")]
7pub use url_pkg::ParseError as UrlParseError;
8
9use crate::http::body::Body;
10use crate::http::{StatusCode, error, header};
11use crate::util::{BytesMut, Either};
12
13pub use super::error_default::{DefaultError, Error};
14pub use crate::http::error::BlockingError;
15
16use super::{HttpRequest, HttpResponse};
17
18pub trait ErrorRenderer: Sized + 'static {
19 type Container: ErrorContainer;
20}
21
22pub trait ErrorContainer: error::ResponseError + Sized {
23 fn error_response(&self, req: &HttpRequest) -> HttpResponse;
25}
26
27pub trait WebResponseError<Err = DefaultError>:
29 fmt::Display + fmt::Debug + 'static
30where
31 Err: ErrorRenderer,
32{
33 fn status_code(&self) -> StatusCode {
37 StatusCode::INTERNAL_SERVER_ERROR
38 }
39
40 fn error_response(&self, _: &HttpRequest) -> HttpResponse {
44 let mut resp = HttpResponse::new(self.status_code());
45 let mut buf = BytesMut::new();
46 let _ = write!(&mut buf, "{self}");
47 resp.headers_mut().insert(
48 header::CONTENT_TYPE,
49 header::HeaderValue::from_static("text/plain; charset=utf-8"),
50 );
51 resp.set_body(Body::from(buf))
52 }
53}
54
55impl<Err: ErrorRenderer> WebResponseError<Err> for std::convert::Infallible {}
56
57impl<A, B, Err> WebResponseError<Err> for Either<A, B>
58where
59 A: WebResponseError<Err>,
60 B: WebResponseError<Err>,
61 Err: ErrorRenderer,
62{
63 fn status_code(&self) -> StatusCode {
64 match self {
65 Either::Left(a) => a.status_code(),
66 Either::Right(b) => b.status_code(),
67 }
68 }
69
70 fn error_response(&self, req: &HttpRequest) -> HttpResponse {
71 match self {
72 Either::Left(a) => a.error_response(req),
73 Either::Right(b) => b.error_response(req),
74 }
75 }
76}
77
78#[derive(Debug, Copy, Clone, PartialEq, Eq, thiserror::Error)]
80pub enum StateExtractorError {
81 #[error("App state is not configured, to configure use App::state()")]
82 NotConfigured,
83}
84
85#[derive(Debug, Copy, Clone, PartialEq, Eq, thiserror::Error)]
87pub enum UrlGenerationError {
88 #[error("Resource not found")]
90 ResourceNotFound,
91 #[error("Not all path pattern covered")]
93 NotEnoughElements,
94 #[cfg(feature = "url")]
96 #[error("{0}")]
97 ParseError(
98 #[from]
99 #[source]
100 UrlParseError,
101 ),
102}
103
104#[derive(Debug, thiserror::Error)]
106pub enum UrlencodedError {
107 #[error("Cannot decode chunked transfer encoding")]
109 Chunked,
110 #[error(
112 "Urlencoded payload size is bigger ({size} bytes) than allowed (default: {limit} bytes)"
113 )]
114 Overflow { size: usize, limit: usize },
115 #[error("Payload size is unknown")]
117 UnknownLength,
118 #[error("Content type error")]
120 ContentType,
121 #[error("Parse error")]
123 Parse,
124 #[error("Error that occur during reading payload: {0}")]
126 Payload(
127 #[from]
128 #[source]
129 error::PayloadError,
130 ),
131}
132
133#[derive(Debug, thiserror::Error)]
135pub enum JsonPayloadError {
136 #[error("Json payload size is bigger than allowed")]
138 Overflow,
139 #[error("Content type error")]
141 ContentType,
142 #[error("Json deserialize error: {0}")]
144 Deserialize(
145 #[from]
146 #[source]
147 serde_json::error::Error,
148 ),
149 #[error("Error that occur during reading payload: {0}")]
151 Payload(
152 #[from]
153 #[source]
154 error::PayloadError,
155 ),
156}
157
158#[derive(Debug, thiserror::Error)]
160pub enum PathError {
161 #[error("Path deserialize error: {0}")]
163 Deserialize(
164 #[from]
165 #[source]
166 serde::de::value::Error,
167 ),
168}
169
170#[derive(Debug, thiserror::Error)]
172pub enum QueryPayloadError {
173 #[error("Query deserialize error: {0}")]
175 Deserialize(
176 #[from]
177 #[source]
178 serde::de::value::Error,
179 ),
180}
181
182#[derive(Debug, thiserror::Error)]
183pub enum PayloadError {
184 #[error("{0:?}")]
186 Http(
187 #[from]
188 #[source]
189 error::HttpError,
190 ),
191 #[error("{0}")]
192 Payload(
193 #[from]
194 #[source]
195 error::PayloadError,
196 ),
197 #[error("{0}")]
198 ContentType(
199 #[from]
200 #[source]
201 error::ContentTypeError,
202 ),
203 #[error("Cannot decode body")]
204 Decoding,
205}
206
207pub struct InternalError<T, Err = DefaultError> {
221 cause: T,
222 status: InternalErrorType,
223 _t: PhantomData<Err>,
224}
225
226enum InternalErrorType {
227 Status(StatusCode),
228 Response(RefCell<Option<HttpResponse>>),
229}
230
231impl<T> InternalError<T> {
232 pub fn default(cause: T, status: StatusCode) -> Self {
234 InternalError {
235 cause,
236 status: InternalErrorType::Status(status),
237 _t: PhantomData,
238 }
239 }
240}
241
242impl<T, Err> InternalError<T, Err> {
243 pub fn new(cause: T, status: StatusCode) -> Self {
245 InternalError {
246 cause,
247 status: InternalErrorType::Status(status),
248 _t: PhantomData,
249 }
250 }
251
252 pub fn from_response(cause: T, response: HttpResponse) -> Self {
254 InternalError {
255 cause,
256 status: InternalErrorType::Response(RefCell::new(Some(response))),
257 _t: PhantomData,
258 }
259 }
260}
261
262impl<T, E> fmt::Debug for InternalError<T, E>
263where
264 T: fmt::Debug + 'static,
265{
266 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
267 write!(f, "web::InternalError({:?})", &self.cause)
268 }
269}
270
271impl<T, E> fmt::Display for InternalError<T, E>
272where
273 T: fmt::Display + 'static,
274{
275 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
276 fmt::Display::fmt(&self.cause, f)
277 }
278}
279
280impl<T: fmt::Display + fmt::Debug + 'static, E> std::error::Error for InternalError<T, E> {}
281
282impl<T, E> WebResponseError<E> for InternalError<T, E>
283where
284 T: fmt::Debug + fmt::Display + 'static,
285 E: ErrorRenderer,
286{
287 fn error_response(&self, _: &HttpRequest) -> HttpResponse {
288 crate::http::error::ResponseError::error_response(self)
289 }
290}
291
292impl<T, E> crate::http::error::ResponseError for InternalError<T, E>
293where
294 T: fmt::Debug + fmt::Display + 'static,
295 E: ErrorRenderer,
296{
297 fn error_response(&self) -> HttpResponse {
298 match self.status {
299 InternalErrorType::Status(st) => {
300 let mut res = HttpResponse::new(st);
301 let mut buf = BytesMut::new();
302 let _ = write!(&mut buf, "{self}");
303 res.headers_mut().insert(
304 header::CONTENT_TYPE,
305 header::HeaderValue::from_static("text/plain; charset=utf-8"),
306 );
307 res.set_body(Body::from(buf))
308 }
309 InternalErrorType::Response(ref resp) => {
310 if let Some(resp) = resp.borrow_mut().take() {
311 resp
312 } else {
313 HttpResponse::new(StatusCode::INTERNAL_SERVER_ERROR)
314 }
315 }
316 }
317 }
318}
319
320#[allow(non_snake_case)]
323pub fn ErrorBadRequest<T, E>(err: T) -> InternalError<T, E>
324where
325 T: fmt::Debug + fmt::Display + 'static,
326{
327 InternalError::new(err, StatusCode::BAD_REQUEST)
328}
329
330#[allow(non_snake_case)]
333pub fn ErrorUnauthorized<T, E>(err: T) -> InternalError<T, E>
334where
335 T: fmt::Debug + fmt::Display + 'static,
336{
337 InternalError::new(err, StatusCode::UNAUTHORIZED)
338}
339
340#[allow(non_snake_case)]
343pub fn ErrorPaymentRequired<T, E>(err: T) -> InternalError<T, E>
344where
345 T: fmt::Debug + fmt::Display + 'static,
346{
347 InternalError::new(err, StatusCode::PAYMENT_REQUIRED)
348}
349
350#[allow(non_snake_case)]
353pub fn ErrorForbidden<T, E>(err: T) -> InternalError<T, E>
354where
355 T: fmt::Debug + fmt::Display + 'static,
356{
357 InternalError::new(err, StatusCode::FORBIDDEN)
358}
359
360#[allow(non_snake_case)]
363pub fn ErrorNotFound<T, E>(err: T) -> InternalError<T, E>
364where
365 T: fmt::Debug + fmt::Display + 'static,
366{
367 InternalError::new(err, StatusCode::NOT_FOUND)
368}
369
370#[allow(non_snake_case)]
373pub fn ErrorMethodNotAllowed<T, E>(err: T) -> InternalError<T, E>
374where
375 T: fmt::Debug + fmt::Display + 'static,
376{
377 InternalError::new(err, StatusCode::METHOD_NOT_ALLOWED)
378}
379
380#[allow(non_snake_case)]
383pub fn ErrorNotAcceptable<T, E>(err: T) -> InternalError<T, E>
384where
385 T: fmt::Debug + fmt::Display + 'static,
386{
387 InternalError::new(err, StatusCode::NOT_ACCEPTABLE)
388}
389
390#[allow(non_snake_case)]
393pub fn ErrorProxyAuthenticationRequired<T, E>(err: T) -> InternalError<T, E>
394where
395 T: fmt::Debug + fmt::Display + 'static,
396{
397 InternalError::new(err, StatusCode::PROXY_AUTHENTICATION_REQUIRED)
398}
399
400#[allow(non_snake_case)]
403pub fn ErrorRequestTimeout<T, E>(err: T) -> InternalError<T, E>
404where
405 T: fmt::Debug + fmt::Display + 'static,
406{
407 InternalError::new(err, StatusCode::REQUEST_TIMEOUT)
408}
409
410#[allow(non_snake_case)]
413pub fn ErrorConflict<T, E>(err: T) -> InternalError<T, E>
414where
415 T: fmt::Debug + fmt::Display + 'static,
416{
417 InternalError::new(err, StatusCode::CONFLICT)
418}
419
420#[allow(non_snake_case)]
423pub fn ErrorGone<T, E>(err: T) -> InternalError<T, E>
424where
425 T: fmt::Debug + fmt::Display + 'static,
426{
427 InternalError::new(err, StatusCode::GONE)
428}
429
430#[allow(non_snake_case)]
433pub fn ErrorLengthRequired<T, E>(err: T) -> InternalError<T, E>
434where
435 T: fmt::Debug + fmt::Display + 'static,
436{
437 InternalError::new(err, StatusCode::LENGTH_REQUIRED)
438}
439
440#[allow(non_snake_case)]
443pub fn ErrorPayloadTooLarge<T, E>(err: T) -> InternalError<T, E>
444where
445 T: fmt::Debug + fmt::Display + 'static,
446{
447 InternalError::new(err, StatusCode::PAYLOAD_TOO_LARGE)
448}
449
450#[allow(non_snake_case)]
453pub fn ErrorUriTooLong<T, E>(err: T) -> InternalError<T, E>
454where
455 T: fmt::Debug + fmt::Display + 'static,
456{
457 InternalError::new(err, StatusCode::URI_TOO_LONG)
458}
459
460#[allow(non_snake_case)]
463pub fn ErrorUnsupportedMediaType<T, E>(err: T) -> InternalError<T, E>
464where
465 T: fmt::Debug + fmt::Display + 'static,
466{
467 InternalError::new(err, StatusCode::UNSUPPORTED_MEDIA_TYPE)
468}
469
470#[allow(non_snake_case)]
473pub fn ErrorRangeNotSatisfiable<T, E>(err: T) -> InternalError<T, E>
474where
475 T: fmt::Debug + fmt::Display + 'static,
476{
477 InternalError::new(err, StatusCode::RANGE_NOT_SATISFIABLE)
478}
479
480#[allow(non_snake_case)]
483pub fn ErrorImATeapot<T, E>(err: T) -> InternalError<T, E>
484where
485 T: fmt::Debug + fmt::Display + 'static,
486{
487 InternalError::new(err, StatusCode::IM_A_TEAPOT)
488}
489
490#[allow(non_snake_case)]
493pub fn ErrorMisdirectedRequest<T, E>(err: T) -> InternalError<T, E>
494where
495 T: fmt::Debug + fmt::Display + 'static,
496{
497 InternalError::new(err, StatusCode::MISDIRECTED_REQUEST)
498}
499
500#[allow(non_snake_case)]
503pub fn ErrorUnprocessableEntity<T, E>(err: T) -> InternalError<T, E>
504where
505 T: fmt::Debug + fmt::Display + 'static,
506{
507 InternalError::new(err, StatusCode::UNPROCESSABLE_ENTITY)
508}
509
510#[allow(non_snake_case)]
513pub fn ErrorLocked<T, E>(err: T) -> InternalError<T, E>
514where
515 T: fmt::Debug + fmt::Display + 'static,
516{
517 InternalError::new(err, StatusCode::LOCKED)
518}
519
520#[allow(non_snake_case)]
523pub fn ErrorFailedDependency<T, E>(err: T) -> InternalError<T, E>
524where
525 T: fmt::Debug + fmt::Display + 'static,
526{
527 InternalError::new(err, StatusCode::FAILED_DEPENDENCY)
528}
529
530#[allow(non_snake_case)]
533pub fn ErrorUpgradeRequired<T, E>(err: T) -> InternalError<T, E>
534where
535 T: fmt::Debug + fmt::Display + 'static,
536{
537 InternalError::new(err, StatusCode::UPGRADE_REQUIRED)
538}
539
540#[allow(non_snake_case)]
543pub fn ErrorPreconditionFailed<T, E>(err: T) -> InternalError<T, E>
544where
545 T: fmt::Debug + fmt::Display + 'static,
546{
547 InternalError::new(err, StatusCode::PRECONDITION_FAILED)
548}
549
550#[allow(non_snake_case)]
553pub fn ErrorPreconditionRequired<T, E>(err: T) -> InternalError<T, E>
554where
555 T: fmt::Debug + fmt::Display + 'static,
556{
557 InternalError::new(err, StatusCode::PRECONDITION_REQUIRED)
558}
559
560#[allow(non_snake_case)]
563pub fn ErrorTooManyRequests<T, E>(err: T) -> InternalError<T, E>
564where
565 T: fmt::Debug + fmt::Display + 'static,
566{
567 InternalError::new(err, StatusCode::TOO_MANY_REQUESTS)
568}
569
570#[allow(non_snake_case)]
573pub fn ErrorRequestHeaderFieldsTooLarge<T, E>(err: T) -> InternalError<T, E>
574where
575 T: fmt::Debug + fmt::Display + 'static,
576{
577 InternalError::new(err, StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE)
578}
579
580#[allow(non_snake_case)]
583pub fn ErrorUnavailableForLegalReasons<T, E>(err: T) -> InternalError<T, E>
584where
585 T: fmt::Debug + fmt::Display + 'static,
586{
587 InternalError::new(err, StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS)
588}
589
590#[allow(non_snake_case)]
593pub fn ErrorExpectationFailed<T, E>(err: T) -> InternalError<T, E>
594where
595 T: fmt::Debug + fmt::Display + 'static,
596{
597 InternalError::new(err, StatusCode::EXPECTATION_FAILED)
598}
599
600#[allow(non_snake_case)]
603pub fn ErrorInternalServerError<T, E>(err: T) -> InternalError<T, E>
604where
605 T: fmt::Debug + fmt::Display + 'static,
606{
607 InternalError::new(err, StatusCode::INTERNAL_SERVER_ERROR)
608}
609
610#[allow(non_snake_case)]
613pub fn ErrorNotImplemented<T, E>(err: T) -> InternalError<T, E>
614where
615 T: fmt::Debug + fmt::Display + 'static,
616{
617 InternalError::new(err, StatusCode::NOT_IMPLEMENTED)
618}
619
620#[allow(non_snake_case)]
623pub fn ErrorBadGateway<T, E>(err: T) -> InternalError<T, E>
624where
625 T: fmt::Debug + fmt::Display + 'static,
626{
627 InternalError::new(err, StatusCode::BAD_GATEWAY)
628}
629
630#[allow(non_snake_case)]
633pub fn ErrorServiceUnavailable<T, E>(err: T) -> InternalError<T, E>
634where
635 T: fmt::Debug + fmt::Display + 'static,
636{
637 InternalError::new(err, StatusCode::SERVICE_UNAVAILABLE)
638}
639
640#[allow(non_snake_case)]
643pub fn ErrorGatewayTimeout<T, E>(err: T) -> InternalError<T, E>
644where
645 T: fmt::Debug + fmt::Display + 'static,
646{
647 InternalError::new(err, StatusCode::GATEWAY_TIMEOUT)
648}
649
650#[allow(non_snake_case)]
653pub fn ErrorHttpVersionNotSupported<T, E>(err: T) -> InternalError<T, E>
654where
655 T: fmt::Debug + fmt::Display + 'static,
656{
657 InternalError::new(err, StatusCode::HTTP_VERSION_NOT_SUPPORTED)
658}
659
660#[allow(non_snake_case)]
663pub fn ErrorVariantAlsoNegotiates<T, E>(err: T) -> InternalError<T, E>
664where
665 T: fmt::Debug + fmt::Display + 'static,
666{
667 InternalError::new(err, StatusCode::VARIANT_ALSO_NEGOTIATES)
668}
669
670#[allow(non_snake_case)]
673pub fn ErrorInsufficientStorage<T, E>(err: T) -> InternalError<T, E>
674where
675 T: fmt::Debug + fmt::Display + 'static,
676{
677 InternalError::new(err, StatusCode::INSUFFICIENT_STORAGE)
678}
679
680#[allow(non_snake_case)]
683pub fn ErrorLoopDetected<T, E>(err: T) -> InternalError<T, E>
684where
685 T: fmt::Debug + fmt::Display + 'static,
686{
687 InternalError::new(err, StatusCode::LOOP_DETECTED)
688}
689
690#[allow(non_snake_case)]
693pub fn ErrorNotExtended<T, E>(err: T) -> InternalError<T, E>
694where
695 T: fmt::Debug + fmt::Display + 'static,
696{
697 InternalError::new(err, StatusCode::NOT_EXTENDED)
698}
699
700#[allow(non_snake_case)]
703pub fn ErrorNetworkAuthenticationRequired<T, E>(err: T) -> InternalError<T, E>
704where
705 T: fmt::Debug + fmt::Display + 'static,
706{
707 InternalError::new(err, StatusCode::NETWORK_AUTHENTICATION_REQUIRED)
708}
709
710#[cfg(test)]
711mod tests {
712 use std::io;
713
714 use super::*;
715 use crate::client::error::{ClientError, ConnectError};
716 use crate::{http, web::test::TestRequest};
717
718 #[test]
719 fn test_into_error() {
720 let err = UrlencodedError::UnknownLength;
721 let e: Error = err.into();
722 let s = format!("{e}");
723 assert!(s.contains("Payload size is unknown"));
724
725 let e = Error::new(UrlencodedError::UnknownLength);
726 let s = format!("{e:?}");
727 assert!(s.contains("UnknownLength"));
728
729 let res = crate::http::ResponseError::error_response(&e);
730 assert_eq!(res.status(), StatusCode::LENGTH_REQUIRED);
731 assert_eq!(
732 e.as_response_error().status_code(),
733 StatusCode::LENGTH_REQUIRED
734 );
735 }
736
737 #[test]
738 fn test_other_errors() {
739 use crate::util::timeout::TimeoutError;
740
741 let req = TestRequest::default().to_http_request();
742 let resp =
743 Error::from(TimeoutError::<UrlencodedError>::Timeout).error_response(&req);
744 assert_eq!(resp.status(), StatusCode::GATEWAY_TIMEOUT);
745
746 let resp = Error::from(TimeoutError::<UrlencodedError>::Service(
747 UrlencodedError::Chunked,
748 ))
749 .error_response(&req);
750 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
751
752 let resp = WebResponseError::<DefaultError>::error_response(
753 &ClientError::Connect(ConnectError::Timeout),
754 &req,
755 );
756 assert_eq!(resp.status(), StatusCode::GATEWAY_TIMEOUT);
757
758 let resp = WebResponseError::<DefaultError>::error_response(
759 &ClientError::Connect(ConnectError::SslIsNotSupported),
760 &req,
761 );
762 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
763
764 let resp = WebResponseError::<DefaultError>::error_response(
765 &ClientError::TunnelNotSupported,
766 &req,
767 );
768 assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
769
770 #[cfg(feature = "cookie")]
771 {
772 let resp: HttpResponse = WebResponseError::<DefaultError>::error_response(
773 &coo_kie::ParseError::EmptyName,
774 &req,
775 );
776 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
777 }
778
779 let resp = WebResponseError::<DefaultError>::error_response(
780 &crate::http::error::ContentTypeError::ParseError,
781 &req,
782 );
783 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
784
785 let err = serde_urlencoded::from_str::<i32>("bad query").unwrap_err();
786 let resp = WebResponseError::<DefaultError>::error_response(&err, &req);
787 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
788
789 let err = PayloadError::Decoding;
790 let resp = WebResponseError::<DefaultError>::error_response(&err, &req);
791 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
792
793 #[allow(invalid_from_utf8)]
794 let err = std::str::from_utf8(b"\xF0").unwrap_err();
795 let resp = WebResponseError::<DefaultError>::error_response(&err, &req);
796 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
797
798 let err = http::error::PayloadError::EncodingCorrupted;
799 let resp = WebResponseError::<DefaultError>::error_response(&err, &req);
800 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
801 }
802
803 #[test]
804 fn test_either_error() {
805 let req = TestRequest::default().to_http_request();
806
807 let err: Either<ClientError, PayloadError> =
808 Either::Left(ClientError::TunnelNotSupported);
809 let code = WebResponseError::<DefaultError>::status_code(&err);
810 assert_eq!(code, StatusCode::INTERNAL_SERVER_ERROR);
811 let resp = WebResponseError::<DefaultError>::error_response(&err, &req);
812 assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
813
814 let err: Either<ClientError, PayloadError> = Either::Right(PayloadError::Decoding);
815 let code = WebResponseError::<DefaultError>::status_code(&err);
816 assert_eq!(code, StatusCode::BAD_REQUEST);
817 let resp = WebResponseError::<DefaultError>::error_response(&err, &req);
818 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
819 }
820
821 #[test]
822 fn test_io_error() {
823 assert_eq!(
824 StatusCode::NOT_FOUND,
825 WebResponseError::<DefaultError>::status_code(&io::Error::new(
826 io::ErrorKind::NotFound,
827 ""
828 )),
829 );
830 assert_eq!(
831 StatusCode::FORBIDDEN,
832 WebResponseError::<DefaultError>::status_code(&io::Error::new(
833 io::ErrorKind::PermissionDenied,
834 ""
835 )),
836 );
837 assert_eq!(
838 StatusCode::INTERNAL_SERVER_ERROR,
839 WebResponseError::<DefaultError>::status_code(&io::Error::other("")),
840 );
841 }
842
843 #[test]
844 fn test_urlencoded_error() {
845 let req = TestRequest::default().to_http_request();
846 let resp: HttpResponse = WebResponseError::<DefaultError>::error_response(
847 &UrlencodedError::Overflow { size: 0, limit: 0 },
848 &req,
849 );
850 assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
851 let resp: HttpResponse = WebResponseError::<DefaultError>::error_response(
852 &UrlencodedError::UnknownLength,
853 &req,
854 );
855 assert_eq!(resp.status(), StatusCode::LENGTH_REQUIRED);
856 let resp: HttpResponse = WebResponseError::<DefaultError>::error_response(
857 &UrlencodedError::ContentType,
858 &req,
859 );
860 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
861 }
862
863 #[test]
864 fn test_json_payload_error() {
865 let req = TestRequest::default().to_http_request();
866 let resp: HttpResponse = WebResponseError::<DefaultError>::error_response(
867 &JsonPayloadError::Overflow,
868 &req,
869 );
870 assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
871 let resp: HttpResponse = WebResponseError::<DefaultError>::error_response(
872 &JsonPayloadError::ContentType,
873 &req,
874 );
875 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
876 }
877
878 #[test]
879 fn test_query_payload_error() {
880 let req = TestRequest::default().to_http_request();
881
882 let err = QueryPayloadError::Deserialize(
883 serde_urlencoded::from_str::<i32>("bad query").unwrap_err(),
884 );
885
886 let resp: HttpResponse =
887 WebResponseError::<DefaultError>::error_response(&err, &req);
888 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
889 assert_eq!(
890 WebResponseError::<DefaultError>::status_code(&err),
891 StatusCode::BAD_REQUEST
892 );
893 }
894
895 #[test]
896 fn test_path_error() {
897 let req = TestRequest::default().to_http_request();
898 let err = PathError::Deserialize(
899 serde_urlencoded::from_str::<i32>("bad path").unwrap_err(),
900 );
901 let resp: HttpResponse =
902 WebResponseError::<DefaultError>::error_response(&err, &req);
903 assert_eq!(resp.status(), StatusCode::NOT_FOUND);
904 assert_eq!(
905 WebResponseError::<DefaultError>::status_code(&err),
906 StatusCode::NOT_FOUND
907 );
908 }
909
910 #[test]
911 fn test_handshake_error() {
912 use crate::ws::error::HandshakeError;
913
914 let req = TestRequest::default().to_http_request();
915
916 let resp = HandshakeError::GetMethodRequired.error_response(&req);
917 assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
918 let resp = HandshakeError::NoWebsocketUpgrade.error_response(&req);
919 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
920 let resp = HandshakeError::NoConnectionUpgrade.error_response(&req);
921 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
922 let resp = HandshakeError::NoVersionHeader.error_response(&req);
923 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
924 let resp = HandshakeError::UnsupportedVersion.error_response(&req);
925 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
926 let resp = HandshakeError::BadWebsocketKey.error_response(&req);
927 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
928 }
929
930 #[test]
931 fn test_error_helpers() {
932 let err = ErrorBadRequest::<_, DefaultError>("err");
933 assert!(format!("{err:?}").contains("web::InternalError"));
934
935 let err: InternalError<_, DefaultError> =
936 InternalError::from_response("err", HttpResponse::BadRequest().finish());
937 let r: HttpResponse = err.into();
938 assert_eq!(r.status(), StatusCode::BAD_REQUEST);
939
940 let r: HttpResponse = ErrorBadRequest::<_, DefaultError>("err").into();
941 assert_eq!(r.status(), StatusCode::BAD_REQUEST);
942
943 let r: HttpResponse = ErrorUnauthorized::<_, DefaultError>("err").into();
944 assert_eq!(r.status(), StatusCode::UNAUTHORIZED);
945
946 let r: HttpResponse = ErrorPaymentRequired::<_, DefaultError>("err").into();
947 assert_eq!(r.status(), StatusCode::PAYMENT_REQUIRED);
948
949 let r: HttpResponse = ErrorForbidden::<_, DefaultError>("err").into();
950 assert_eq!(r.status(), StatusCode::FORBIDDEN);
951
952 let r: HttpResponse = ErrorNotFound::<_, DefaultError>("err").into();
953 assert_eq!(r.status(), StatusCode::NOT_FOUND);
954
955 let r: HttpResponse = ErrorMethodNotAllowed::<_, DefaultError>("err").into();
956 assert_eq!(r.status(), StatusCode::METHOD_NOT_ALLOWED);
957
958 let r: HttpResponse = ErrorNotAcceptable::<_, DefaultError>("err").into();
959 assert_eq!(r.status(), StatusCode::NOT_ACCEPTABLE);
960
961 let r: HttpResponse =
962 ErrorProxyAuthenticationRequired::<_, DefaultError>("err").into();
963 assert_eq!(r.status(), StatusCode::PROXY_AUTHENTICATION_REQUIRED);
964
965 let r: HttpResponse = ErrorRequestTimeout::<_, DefaultError>("err").into();
966 assert_eq!(r.status(), StatusCode::REQUEST_TIMEOUT);
967
968 let r: HttpResponse = ErrorConflict::<_, DefaultError>("err").into();
969 assert_eq!(r.status(), StatusCode::CONFLICT);
970
971 let r: HttpResponse = ErrorGone::<_, DefaultError>("err").into();
972 assert_eq!(r.status(), StatusCode::GONE);
973
974 let r: HttpResponse = ErrorLengthRequired::<_, DefaultError>("err").into();
975 assert_eq!(r.status(), StatusCode::LENGTH_REQUIRED);
976
977 let r: HttpResponse = ErrorPreconditionFailed::<_, DefaultError>("err").into();
978 assert_eq!(r.status(), StatusCode::PRECONDITION_FAILED);
979
980 let r: HttpResponse = ErrorPayloadTooLarge::<_, DefaultError>("err").into();
981 assert_eq!(r.status(), StatusCode::PAYLOAD_TOO_LARGE);
982
983 let r: HttpResponse = ErrorUriTooLong::<_, DefaultError>("err").into();
984 assert_eq!(r.status(), StatusCode::URI_TOO_LONG);
985
986 let r: HttpResponse = ErrorUnsupportedMediaType::<_, DefaultError>("err").into();
987 assert_eq!(r.status(), StatusCode::UNSUPPORTED_MEDIA_TYPE);
988
989 let r: HttpResponse = ErrorRangeNotSatisfiable::<_, DefaultError>("err").into();
990 assert_eq!(r.status(), StatusCode::RANGE_NOT_SATISFIABLE);
991
992 let r: HttpResponse = ErrorExpectationFailed::<_, DefaultError>("err").into();
993 assert_eq!(r.status(), StatusCode::EXPECTATION_FAILED);
994
995 let r: HttpResponse = ErrorImATeapot::<_, DefaultError>("err").into();
996 assert_eq!(r.status(), StatusCode::IM_A_TEAPOT);
997
998 let r: HttpResponse = ErrorMisdirectedRequest::<_, DefaultError>("err").into();
999 assert_eq!(r.status(), StatusCode::MISDIRECTED_REQUEST);
1000
1001 let r: HttpResponse = ErrorUnprocessableEntity::<_, DefaultError>("err").into();
1002 assert_eq!(r.status(), StatusCode::UNPROCESSABLE_ENTITY);
1003
1004 let r: HttpResponse = ErrorLocked::<_, DefaultError>("err").into();
1005 assert_eq!(r.status(), StatusCode::LOCKED);
1006
1007 let r: HttpResponse = ErrorFailedDependency::<_, DefaultError>("err").into();
1008 assert_eq!(r.status(), StatusCode::FAILED_DEPENDENCY);
1009
1010 let r: HttpResponse = ErrorUpgradeRequired::<_, DefaultError>("err").into();
1011 assert_eq!(r.status(), StatusCode::UPGRADE_REQUIRED);
1012
1013 let r: HttpResponse = ErrorPreconditionRequired::<_, DefaultError>("err").into();
1014 assert_eq!(r.status(), StatusCode::PRECONDITION_REQUIRED);
1015
1016 let r: HttpResponse = ErrorTooManyRequests::<_, DefaultError>("err").into();
1017 assert_eq!(r.status(), StatusCode::TOO_MANY_REQUESTS);
1018
1019 let r: HttpResponse =
1020 ErrorRequestHeaderFieldsTooLarge::<_, DefaultError>("err").into();
1021 assert_eq!(r.status(), StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE);
1022
1023 let r: HttpResponse =
1024 ErrorUnavailableForLegalReasons::<_, DefaultError>("err").into();
1025 assert_eq!(r.status(), StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS);
1026
1027 let r: HttpResponse = ErrorInternalServerError::<_, DefaultError>("err").into();
1028 assert_eq!(r.status(), StatusCode::INTERNAL_SERVER_ERROR);
1029
1030 let r: HttpResponse = ErrorNotImplemented::<_, DefaultError>("err").into();
1031 assert_eq!(r.status(), StatusCode::NOT_IMPLEMENTED);
1032
1033 let r: HttpResponse = ErrorBadGateway::<_, DefaultError>("err").into();
1034 assert_eq!(r.status(), StatusCode::BAD_GATEWAY);
1035
1036 let r: HttpResponse = ErrorServiceUnavailable::<_, DefaultError>("err").into();
1037 assert_eq!(r.status(), StatusCode::SERVICE_UNAVAILABLE);
1038
1039 let r: HttpResponse = ErrorGatewayTimeout::<_, DefaultError>("err").into();
1040 assert_eq!(r.status(), StatusCode::GATEWAY_TIMEOUT);
1041
1042 let r: HttpResponse = ErrorHttpVersionNotSupported::<_, DefaultError>("err").into();
1043 assert_eq!(r.status(), StatusCode::HTTP_VERSION_NOT_SUPPORTED);
1044
1045 let r: HttpResponse = ErrorVariantAlsoNegotiates::<_, DefaultError>("err").into();
1046 assert_eq!(r.status(), StatusCode::VARIANT_ALSO_NEGOTIATES);
1047
1048 let r: HttpResponse = ErrorInsufficientStorage::<_, DefaultError>("err").into();
1049 assert_eq!(r.status(), StatusCode::INSUFFICIENT_STORAGE);
1050
1051 let r: HttpResponse = ErrorLoopDetected::<_, DefaultError>("err").into();
1052 assert_eq!(r.status(), StatusCode::LOOP_DETECTED);
1053
1054 let r: HttpResponse = ErrorNotExtended::<_, DefaultError>("err").into();
1055 assert_eq!(r.status(), StatusCode::NOT_EXTENDED);
1056
1057 let r: HttpResponse =
1058 ErrorNetworkAuthenticationRequired::<_, DefaultError>("err").into();
1059 assert_eq!(r.status(), StatusCode::NETWORK_AUTHENTICATION_REQUIRED);
1060 }
1061}