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(#[from] UrlParseError),
98}
99
100#[derive(Debug, thiserror::Error)]
102pub enum UrlencodedError {
103 #[error("Cannot decode chunked transfer encoding")]
105 Chunked,
106 #[error(
108 "Urlencoded payload size is bigger ({size} bytes) than allowed (default: {limit} bytes)"
109 )]
110 Overflow { size: usize, limit: usize },
111 #[error("Payload size is unknown")]
113 UnknownLength,
114 #[error("Content type error")]
116 ContentType,
117 #[error("Parse error")]
119 Parse,
120 #[error("Error that occur during reading payload: {0}")]
122 Payload(#[from] error::PayloadError),
123}
124
125#[derive(Debug, thiserror::Error)]
127pub enum JsonPayloadError {
128 #[error("Json payload size is bigger than allowed")]
130 Overflow,
131 #[error("Content type error")]
133 ContentType,
134 #[error("Json deserialize error: {0}")]
136 Deserialize(#[from] serde_json::error::Error),
137 #[error("Error that occur during reading payload: {0}")]
139 Payload(#[from] error::PayloadError),
140}
141
142#[derive(Debug, thiserror::Error)]
144pub enum PathError {
145 #[error("Path deserialize error: {0}")]
147 Deserialize(#[from] serde::de::value::Error),
148}
149
150#[derive(Debug, thiserror::Error)]
152pub enum QueryPayloadError {
153 #[error("Query deserialize error: {0}")]
155 Deserialize(#[from] serde::de::value::Error),
156}
157
158#[derive(Debug, thiserror::Error)]
159pub enum PayloadError {
160 #[error("{0:?}")]
162 Http(#[from] error::HttpError),
163 #[error("{0}")]
164 Payload(#[from] error::PayloadError),
165 #[error("{0}")]
166 ContentType(#[from] error::ContentTypeError),
167 #[error("Cannot decode body")]
168 Decoding,
169}
170
171pub struct InternalError<T, Err = DefaultError> {
185 cause: T,
186 status: InternalErrorType,
187 _t: PhantomData<Err>,
188}
189
190enum InternalErrorType {
191 Status(StatusCode),
192 Response(RefCell<Option<HttpResponse>>),
193}
194
195impl<T> InternalError<T> {
196 pub fn default(cause: T, status: StatusCode) -> Self {
198 InternalError {
199 cause,
200 status: InternalErrorType::Status(status),
201 _t: PhantomData,
202 }
203 }
204}
205
206impl<T, Err> InternalError<T, Err> {
207 pub fn new(cause: T, status: StatusCode) -> Self {
209 InternalError {
210 cause,
211 status: InternalErrorType::Status(status),
212 _t: PhantomData,
213 }
214 }
215
216 pub fn from_response(cause: T, response: HttpResponse) -> Self {
218 InternalError {
219 cause,
220 status: InternalErrorType::Response(RefCell::new(Some(response))),
221 _t: PhantomData,
222 }
223 }
224}
225
226impl<T, E> fmt::Debug for InternalError<T, E>
227where
228 T: fmt::Debug + 'static,
229{
230 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231 write!(f, "web::InternalError({:?})", &self.cause)
232 }
233}
234
235impl<T, E> fmt::Display for InternalError<T, E>
236where
237 T: fmt::Display + 'static,
238{
239 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
240 fmt::Display::fmt(&self.cause, f)
241 }
242}
243
244impl<T: fmt::Display + fmt::Debug + 'static, E> std::error::Error for InternalError<T, E> {}
245
246impl<T, E> WebResponseError<E> for InternalError<T, E>
247where
248 T: fmt::Debug + fmt::Display + 'static,
249 E: ErrorRenderer,
250{
251 fn error_response(&self, _: &HttpRequest) -> HttpResponse {
252 crate::http::error::ResponseError::error_response(self)
253 }
254}
255
256impl<T, E> crate::http::error::ResponseError for InternalError<T, E>
257where
258 T: fmt::Debug + fmt::Display + 'static,
259 E: ErrorRenderer,
260{
261 fn error_response(&self) -> HttpResponse {
262 match self.status {
263 InternalErrorType::Status(st) => {
264 let mut res = HttpResponse::new(st);
265 let mut buf = BytesMut::new();
266 let _ = write!(&mut buf, "{self}");
267 res.headers_mut().insert(
268 header::CONTENT_TYPE,
269 header::HeaderValue::from_static("text/plain; charset=utf-8"),
270 );
271 res.set_body(Body::from(buf))
272 }
273 InternalErrorType::Response(ref resp) => {
274 if let Some(resp) = resp.borrow_mut().take() {
275 resp
276 } else {
277 HttpResponse::new(StatusCode::INTERNAL_SERVER_ERROR)
278 }
279 }
280 }
281 }
282}
283
284#[allow(non_snake_case)]
287pub fn ErrorBadRequest<T, E>(err: T) -> InternalError<T, E>
288where
289 T: fmt::Debug + fmt::Display + 'static,
290{
291 InternalError::new(err, StatusCode::BAD_REQUEST)
292}
293
294#[allow(non_snake_case)]
297pub fn ErrorUnauthorized<T, E>(err: T) -> InternalError<T, E>
298where
299 T: fmt::Debug + fmt::Display + 'static,
300{
301 InternalError::new(err, StatusCode::UNAUTHORIZED)
302}
303
304#[allow(non_snake_case)]
307pub fn ErrorPaymentRequired<T, E>(err: T) -> InternalError<T, E>
308where
309 T: fmt::Debug + fmt::Display + 'static,
310{
311 InternalError::new(err, StatusCode::PAYMENT_REQUIRED)
312}
313
314#[allow(non_snake_case)]
317pub fn ErrorForbidden<T, E>(err: T) -> InternalError<T, E>
318where
319 T: fmt::Debug + fmt::Display + 'static,
320{
321 InternalError::new(err, StatusCode::FORBIDDEN)
322}
323
324#[allow(non_snake_case)]
327pub fn ErrorNotFound<T, E>(err: T) -> InternalError<T, E>
328where
329 T: fmt::Debug + fmt::Display + 'static,
330{
331 InternalError::new(err, StatusCode::NOT_FOUND)
332}
333
334#[allow(non_snake_case)]
337pub fn ErrorMethodNotAllowed<T, E>(err: T) -> InternalError<T, E>
338where
339 T: fmt::Debug + fmt::Display + 'static,
340{
341 InternalError::new(err, StatusCode::METHOD_NOT_ALLOWED)
342}
343
344#[allow(non_snake_case)]
347pub fn ErrorNotAcceptable<T, E>(err: T) -> InternalError<T, E>
348where
349 T: fmt::Debug + fmt::Display + 'static,
350{
351 InternalError::new(err, StatusCode::NOT_ACCEPTABLE)
352}
353
354#[allow(non_snake_case)]
357pub fn ErrorProxyAuthenticationRequired<T, E>(err: T) -> InternalError<T, E>
358where
359 T: fmt::Debug + fmt::Display + 'static,
360{
361 InternalError::new(err, StatusCode::PROXY_AUTHENTICATION_REQUIRED)
362}
363
364#[allow(non_snake_case)]
367pub fn ErrorRequestTimeout<T, E>(err: T) -> InternalError<T, E>
368where
369 T: fmt::Debug + fmt::Display + 'static,
370{
371 InternalError::new(err, StatusCode::REQUEST_TIMEOUT)
372}
373
374#[allow(non_snake_case)]
377pub fn ErrorConflict<T, E>(err: T) -> InternalError<T, E>
378where
379 T: fmt::Debug + fmt::Display + 'static,
380{
381 InternalError::new(err, StatusCode::CONFLICT)
382}
383
384#[allow(non_snake_case)]
387pub fn ErrorGone<T, E>(err: T) -> InternalError<T, E>
388where
389 T: fmt::Debug + fmt::Display + 'static,
390{
391 InternalError::new(err, StatusCode::GONE)
392}
393
394#[allow(non_snake_case)]
397pub fn ErrorLengthRequired<T, E>(err: T) -> InternalError<T, E>
398where
399 T: fmt::Debug + fmt::Display + 'static,
400{
401 InternalError::new(err, StatusCode::LENGTH_REQUIRED)
402}
403
404#[allow(non_snake_case)]
407pub fn ErrorPayloadTooLarge<T, E>(err: T) -> InternalError<T, E>
408where
409 T: fmt::Debug + fmt::Display + 'static,
410{
411 InternalError::new(err, StatusCode::PAYLOAD_TOO_LARGE)
412}
413
414#[allow(non_snake_case)]
417pub fn ErrorUriTooLong<T, E>(err: T) -> InternalError<T, E>
418where
419 T: fmt::Debug + fmt::Display + 'static,
420{
421 InternalError::new(err, StatusCode::URI_TOO_LONG)
422}
423
424#[allow(non_snake_case)]
427pub fn ErrorUnsupportedMediaType<T, E>(err: T) -> InternalError<T, E>
428where
429 T: fmt::Debug + fmt::Display + 'static,
430{
431 InternalError::new(err, StatusCode::UNSUPPORTED_MEDIA_TYPE)
432}
433
434#[allow(non_snake_case)]
437pub fn ErrorRangeNotSatisfiable<T, E>(err: T) -> InternalError<T, E>
438where
439 T: fmt::Debug + fmt::Display + 'static,
440{
441 InternalError::new(err, StatusCode::RANGE_NOT_SATISFIABLE)
442}
443
444#[allow(non_snake_case)]
447pub fn ErrorImATeapot<T, E>(err: T) -> InternalError<T, E>
448where
449 T: fmt::Debug + fmt::Display + 'static,
450{
451 InternalError::new(err, StatusCode::IM_A_TEAPOT)
452}
453
454#[allow(non_snake_case)]
457pub fn ErrorMisdirectedRequest<T, E>(err: T) -> InternalError<T, E>
458where
459 T: fmt::Debug + fmt::Display + 'static,
460{
461 InternalError::new(err, StatusCode::MISDIRECTED_REQUEST)
462}
463
464#[allow(non_snake_case)]
467pub fn ErrorUnprocessableEntity<T, E>(err: T) -> InternalError<T, E>
468where
469 T: fmt::Debug + fmt::Display + 'static,
470{
471 InternalError::new(err, StatusCode::UNPROCESSABLE_ENTITY)
472}
473
474#[allow(non_snake_case)]
477pub fn ErrorLocked<T, E>(err: T) -> InternalError<T, E>
478where
479 T: fmt::Debug + fmt::Display + 'static,
480{
481 InternalError::new(err, StatusCode::LOCKED)
482}
483
484#[allow(non_snake_case)]
487pub fn ErrorFailedDependency<T, E>(err: T) -> InternalError<T, E>
488where
489 T: fmt::Debug + fmt::Display + 'static,
490{
491 InternalError::new(err, StatusCode::FAILED_DEPENDENCY)
492}
493
494#[allow(non_snake_case)]
497pub fn ErrorUpgradeRequired<T, E>(err: T) -> InternalError<T, E>
498where
499 T: fmt::Debug + fmt::Display + 'static,
500{
501 InternalError::new(err, StatusCode::UPGRADE_REQUIRED)
502}
503
504#[allow(non_snake_case)]
507pub fn ErrorPreconditionFailed<T, E>(err: T) -> InternalError<T, E>
508where
509 T: fmt::Debug + fmt::Display + 'static,
510{
511 InternalError::new(err, StatusCode::PRECONDITION_FAILED)
512}
513
514#[allow(non_snake_case)]
517pub fn ErrorPreconditionRequired<T, E>(err: T) -> InternalError<T, E>
518where
519 T: fmt::Debug + fmt::Display + 'static,
520{
521 InternalError::new(err, StatusCode::PRECONDITION_REQUIRED)
522}
523
524#[allow(non_snake_case)]
527pub fn ErrorTooManyRequests<T, E>(err: T) -> InternalError<T, E>
528where
529 T: fmt::Debug + fmt::Display + 'static,
530{
531 InternalError::new(err, StatusCode::TOO_MANY_REQUESTS)
532}
533
534#[allow(non_snake_case)]
537pub fn ErrorRequestHeaderFieldsTooLarge<T, E>(err: T) -> InternalError<T, E>
538where
539 T: fmt::Debug + fmt::Display + 'static,
540{
541 InternalError::new(err, StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE)
542}
543
544#[allow(non_snake_case)]
547pub fn ErrorUnavailableForLegalReasons<T, E>(err: T) -> InternalError<T, E>
548where
549 T: fmt::Debug + fmt::Display + 'static,
550{
551 InternalError::new(err, StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS)
552}
553
554#[allow(non_snake_case)]
557pub fn ErrorExpectationFailed<T, E>(err: T) -> InternalError<T, E>
558where
559 T: fmt::Debug + fmt::Display + 'static,
560{
561 InternalError::new(err, StatusCode::EXPECTATION_FAILED)
562}
563
564#[allow(non_snake_case)]
567pub fn ErrorInternalServerError<T, E>(err: T) -> InternalError<T, E>
568where
569 T: fmt::Debug + fmt::Display + 'static,
570{
571 InternalError::new(err, StatusCode::INTERNAL_SERVER_ERROR)
572}
573
574#[allow(non_snake_case)]
577pub fn ErrorNotImplemented<T, E>(err: T) -> InternalError<T, E>
578where
579 T: fmt::Debug + fmt::Display + 'static,
580{
581 InternalError::new(err, StatusCode::NOT_IMPLEMENTED)
582}
583
584#[allow(non_snake_case)]
587pub fn ErrorBadGateway<T, E>(err: T) -> InternalError<T, E>
588where
589 T: fmt::Debug + fmt::Display + 'static,
590{
591 InternalError::new(err, StatusCode::BAD_GATEWAY)
592}
593
594#[allow(non_snake_case)]
597pub fn ErrorServiceUnavailable<T, E>(err: T) -> InternalError<T, E>
598where
599 T: fmt::Debug + fmt::Display + 'static,
600{
601 InternalError::new(err, StatusCode::SERVICE_UNAVAILABLE)
602}
603
604#[allow(non_snake_case)]
607pub fn ErrorGatewayTimeout<T, E>(err: T) -> InternalError<T, E>
608where
609 T: fmt::Debug + fmt::Display + 'static,
610{
611 InternalError::new(err, StatusCode::GATEWAY_TIMEOUT)
612}
613
614#[allow(non_snake_case)]
617pub fn ErrorHttpVersionNotSupported<T, E>(err: T) -> InternalError<T, E>
618where
619 T: fmt::Debug + fmt::Display + 'static,
620{
621 InternalError::new(err, StatusCode::HTTP_VERSION_NOT_SUPPORTED)
622}
623
624#[allow(non_snake_case)]
627pub fn ErrorVariantAlsoNegotiates<T, E>(err: T) -> InternalError<T, E>
628where
629 T: fmt::Debug + fmt::Display + 'static,
630{
631 InternalError::new(err, StatusCode::VARIANT_ALSO_NEGOTIATES)
632}
633
634#[allow(non_snake_case)]
637pub fn ErrorInsufficientStorage<T, E>(err: T) -> InternalError<T, E>
638where
639 T: fmt::Debug + fmt::Display + 'static,
640{
641 InternalError::new(err, StatusCode::INSUFFICIENT_STORAGE)
642}
643
644#[allow(non_snake_case)]
647pub fn ErrorLoopDetected<T, E>(err: T) -> InternalError<T, E>
648where
649 T: fmt::Debug + fmt::Display + 'static,
650{
651 InternalError::new(err, StatusCode::LOOP_DETECTED)
652}
653
654#[allow(non_snake_case)]
657pub fn ErrorNotExtended<T, E>(err: T) -> InternalError<T, E>
658where
659 T: fmt::Debug + fmt::Display + 'static,
660{
661 InternalError::new(err, StatusCode::NOT_EXTENDED)
662}
663
664#[allow(non_snake_case)]
667pub fn ErrorNetworkAuthenticationRequired<T, E>(err: T) -> InternalError<T, E>
668where
669 T: fmt::Debug + fmt::Display + 'static,
670{
671 InternalError::new(err, StatusCode::NETWORK_AUTHENTICATION_REQUIRED)
672}
673
674#[cfg(test)]
675mod tests {
676 use std::io;
677
678 use super::*;
679 use crate::client::error::{ClientError, ConnectError};
680 use crate::{http, web::test::TestRequest};
681
682 #[test]
683 fn test_into_error() {
684 let err = UrlencodedError::UnknownLength;
685 let e: Error = err.into();
686 let s = format!("{e}");
687 assert!(s.contains("Payload size is unknown"));
688
689 let e = Error::new(UrlencodedError::UnknownLength);
690 let s = format!("{e:?}");
691 assert!(s.contains("UnknownLength"));
692
693 let res = crate::http::ResponseError::error_response(&e);
694 assert_eq!(res.status(), StatusCode::LENGTH_REQUIRED);
695 assert_eq!(
696 e.as_response_error().status_code(),
697 StatusCode::LENGTH_REQUIRED
698 );
699 }
700
701 #[test]
702 fn test_other_errors() {
703 use crate::util::timeout::TimeoutError;
704
705 let req = TestRequest::default().to_http_request();
706 let resp =
707 Error::from(TimeoutError::<UrlencodedError>::Timeout).error_response(&req);
708 assert_eq!(resp.status(), StatusCode::GATEWAY_TIMEOUT);
709
710 let resp = Error::from(TimeoutError::<UrlencodedError>::Service(
711 UrlencodedError::Chunked,
712 ))
713 .error_response(&req);
714 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
715
716 let resp = WebResponseError::<DefaultError>::error_response(
717 &ClientError::Connect(ConnectError::Timeout),
718 &req,
719 );
720 assert_eq!(resp.status(), StatusCode::GATEWAY_TIMEOUT);
721
722 let resp = WebResponseError::<DefaultError>::error_response(
723 &ClientError::Connect(ConnectError::SslIsNotSupported),
724 &req,
725 );
726 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
727
728 let resp = WebResponseError::<DefaultError>::error_response(
729 &ClientError::TunnelNotSupported,
730 &req,
731 );
732 assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
733
734 #[cfg(feature = "cookie")]
735 {
736 let resp: HttpResponse = WebResponseError::<DefaultError>::error_response(
737 &coo_kie::ParseError::EmptyName,
738 &req,
739 );
740 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
741 }
742
743 let resp = WebResponseError::<DefaultError>::error_response(
744 &crate::http::error::ContentTypeError::ParseError,
745 &req,
746 );
747 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
748
749 let err = serde_urlencoded::from_str::<i32>("bad query").unwrap_err();
750 let resp = WebResponseError::<DefaultError>::error_response(&err, &req);
751 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
752
753 let err = PayloadError::Decoding;
754 let resp = WebResponseError::<DefaultError>::error_response(&err, &req);
755 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
756
757 #[allow(invalid_from_utf8)]
758 let err = std::str::from_utf8(b"\xF0").unwrap_err();
759 let resp = WebResponseError::<DefaultError>::error_response(&err, &req);
760 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
761
762 let err = http::error::PayloadError::EncodingCorrupted;
763 let resp = WebResponseError::<DefaultError>::error_response(&err, &req);
764 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
765 }
766
767 #[test]
768 fn test_either_error() {
769 let req = TestRequest::default().to_http_request();
770
771 let err: Either<ClientError, PayloadError> =
772 Either::Left(ClientError::TunnelNotSupported);
773 let code = WebResponseError::<DefaultError>::status_code(&err);
774 assert_eq!(code, StatusCode::INTERNAL_SERVER_ERROR);
775 let resp = WebResponseError::<DefaultError>::error_response(&err, &req);
776 assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
777
778 let err: Either<ClientError, PayloadError> = Either::Right(PayloadError::Decoding);
779 let code = WebResponseError::<DefaultError>::status_code(&err);
780 assert_eq!(code, StatusCode::BAD_REQUEST);
781 let resp = WebResponseError::<DefaultError>::error_response(&err, &req);
782 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
783 }
784
785 #[test]
786 fn test_io_error() {
787 assert_eq!(
788 StatusCode::NOT_FOUND,
789 WebResponseError::<DefaultError>::status_code(&io::Error::new(
790 io::ErrorKind::NotFound,
791 ""
792 )),
793 );
794 assert_eq!(
795 StatusCode::FORBIDDEN,
796 WebResponseError::<DefaultError>::status_code(&io::Error::new(
797 io::ErrorKind::PermissionDenied,
798 ""
799 )),
800 );
801 assert_eq!(
802 StatusCode::INTERNAL_SERVER_ERROR,
803 WebResponseError::<DefaultError>::status_code(&io::Error::other("")),
804 );
805 }
806
807 #[test]
808 fn test_urlencoded_error() {
809 let req = TestRequest::default().to_http_request();
810 let resp: HttpResponse = WebResponseError::<DefaultError>::error_response(
811 &UrlencodedError::Overflow { size: 0, limit: 0 },
812 &req,
813 );
814 assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
815 let resp: HttpResponse = WebResponseError::<DefaultError>::error_response(
816 &UrlencodedError::UnknownLength,
817 &req,
818 );
819 assert_eq!(resp.status(), StatusCode::LENGTH_REQUIRED);
820 let resp: HttpResponse = WebResponseError::<DefaultError>::error_response(
821 &UrlencodedError::ContentType,
822 &req,
823 );
824 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
825 }
826
827 #[test]
828 fn test_json_payload_error() {
829 let req = TestRequest::default().to_http_request();
830 let resp: HttpResponse = WebResponseError::<DefaultError>::error_response(
831 &JsonPayloadError::Overflow,
832 &req,
833 );
834 assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
835 let resp: HttpResponse = WebResponseError::<DefaultError>::error_response(
836 &JsonPayloadError::ContentType,
837 &req,
838 );
839 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
840 }
841
842 #[test]
843 fn test_query_payload_error() {
844 let req = TestRequest::default().to_http_request();
845
846 let err = QueryPayloadError::Deserialize(
847 serde_urlencoded::from_str::<i32>("bad query").unwrap_err(),
848 );
849
850 let resp: HttpResponse =
851 WebResponseError::<DefaultError>::error_response(&err, &req);
852 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
853 assert_eq!(
854 WebResponseError::<DefaultError>::status_code(&err),
855 StatusCode::BAD_REQUEST
856 );
857 }
858
859 #[test]
860 fn test_path_error() {
861 let req = TestRequest::default().to_http_request();
862 let err = PathError::Deserialize(
863 serde_urlencoded::from_str::<i32>("bad path").unwrap_err(),
864 );
865 let resp: HttpResponse =
866 WebResponseError::<DefaultError>::error_response(&err, &req);
867 assert_eq!(resp.status(), StatusCode::NOT_FOUND);
868 assert_eq!(
869 WebResponseError::<DefaultError>::status_code(&err),
870 StatusCode::NOT_FOUND
871 );
872 }
873
874 #[test]
875 fn test_handshake_error() {
876 use crate::ws::error::HandshakeError;
877
878 let req = TestRequest::default().to_http_request();
879
880 let resp = HandshakeError::GetMethodRequired.error_response(&req);
881 assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
882 let resp = HandshakeError::NoWebsocketUpgrade.error_response(&req);
883 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
884 let resp = HandshakeError::NoConnectionUpgrade.error_response(&req);
885 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
886 let resp = HandshakeError::NoVersionHeader.error_response(&req);
887 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
888 let resp = HandshakeError::UnsupportedVersion.error_response(&req);
889 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
890 let resp = HandshakeError::BadWebsocketKey.error_response(&req);
891 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
892 }
893
894 #[test]
895 fn test_error_helpers() {
896 let err = ErrorBadRequest::<_, DefaultError>("err");
897 assert!(format!("{err:?}").contains("web::InternalError"));
898
899 let err: InternalError<_, DefaultError> =
900 InternalError::from_response("err", HttpResponse::BadRequest().finish());
901 let r: HttpResponse = err.into();
902 assert_eq!(r.status(), StatusCode::BAD_REQUEST);
903
904 let r: HttpResponse = ErrorBadRequest::<_, DefaultError>("err").into();
905 assert_eq!(r.status(), StatusCode::BAD_REQUEST);
906
907 let r: HttpResponse = ErrorUnauthorized::<_, DefaultError>("err").into();
908 assert_eq!(r.status(), StatusCode::UNAUTHORIZED);
909
910 let r: HttpResponse = ErrorPaymentRequired::<_, DefaultError>("err").into();
911 assert_eq!(r.status(), StatusCode::PAYMENT_REQUIRED);
912
913 let r: HttpResponse = ErrorForbidden::<_, DefaultError>("err").into();
914 assert_eq!(r.status(), StatusCode::FORBIDDEN);
915
916 let r: HttpResponse = ErrorNotFound::<_, DefaultError>("err").into();
917 assert_eq!(r.status(), StatusCode::NOT_FOUND);
918
919 let r: HttpResponse = ErrorMethodNotAllowed::<_, DefaultError>("err").into();
920 assert_eq!(r.status(), StatusCode::METHOD_NOT_ALLOWED);
921
922 let r: HttpResponse = ErrorNotAcceptable::<_, DefaultError>("err").into();
923 assert_eq!(r.status(), StatusCode::NOT_ACCEPTABLE);
924
925 let r: HttpResponse =
926 ErrorProxyAuthenticationRequired::<_, DefaultError>("err").into();
927 assert_eq!(r.status(), StatusCode::PROXY_AUTHENTICATION_REQUIRED);
928
929 let r: HttpResponse = ErrorRequestTimeout::<_, DefaultError>("err").into();
930 assert_eq!(r.status(), StatusCode::REQUEST_TIMEOUT);
931
932 let r: HttpResponse = ErrorConflict::<_, DefaultError>("err").into();
933 assert_eq!(r.status(), StatusCode::CONFLICT);
934
935 let r: HttpResponse = ErrorGone::<_, DefaultError>("err").into();
936 assert_eq!(r.status(), StatusCode::GONE);
937
938 let r: HttpResponse = ErrorLengthRequired::<_, DefaultError>("err").into();
939 assert_eq!(r.status(), StatusCode::LENGTH_REQUIRED);
940
941 let r: HttpResponse = ErrorPreconditionFailed::<_, DefaultError>("err").into();
942 assert_eq!(r.status(), StatusCode::PRECONDITION_FAILED);
943
944 let r: HttpResponse = ErrorPayloadTooLarge::<_, DefaultError>("err").into();
945 assert_eq!(r.status(), StatusCode::PAYLOAD_TOO_LARGE);
946
947 let r: HttpResponse = ErrorUriTooLong::<_, DefaultError>("err").into();
948 assert_eq!(r.status(), StatusCode::URI_TOO_LONG);
949
950 let r: HttpResponse = ErrorUnsupportedMediaType::<_, DefaultError>("err").into();
951 assert_eq!(r.status(), StatusCode::UNSUPPORTED_MEDIA_TYPE);
952
953 let r: HttpResponse = ErrorRangeNotSatisfiable::<_, DefaultError>("err").into();
954 assert_eq!(r.status(), StatusCode::RANGE_NOT_SATISFIABLE);
955
956 let r: HttpResponse = ErrorExpectationFailed::<_, DefaultError>("err").into();
957 assert_eq!(r.status(), StatusCode::EXPECTATION_FAILED);
958
959 let r: HttpResponse = ErrorImATeapot::<_, DefaultError>("err").into();
960 assert_eq!(r.status(), StatusCode::IM_A_TEAPOT);
961
962 let r: HttpResponse = ErrorMisdirectedRequest::<_, DefaultError>("err").into();
963 assert_eq!(r.status(), StatusCode::MISDIRECTED_REQUEST);
964
965 let r: HttpResponse = ErrorUnprocessableEntity::<_, DefaultError>("err").into();
966 assert_eq!(r.status(), StatusCode::UNPROCESSABLE_ENTITY);
967
968 let r: HttpResponse = ErrorLocked::<_, DefaultError>("err").into();
969 assert_eq!(r.status(), StatusCode::LOCKED);
970
971 let r: HttpResponse = ErrorFailedDependency::<_, DefaultError>("err").into();
972 assert_eq!(r.status(), StatusCode::FAILED_DEPENDENCY);
973
974 let r: HttpResponse = ErrorUpgradeRequired::<_, DefaultError>("err").into();
975 assert_eq!(r.status(), StatusCode::UPGRADE_REQUIRED);
976
977 let r: HttpResponse = ErrorPreconditionRequired::<_, DefaultError>("err").into();
978 assert_eq!(r.status(), StatusCode::PRECONDITION_REQUIRED);
979
980 let r: HttpResponse = ErrorTooManyRequests::<_, DefaultError>("err").into();
981 assert_eq!(r.status(), StatusCode::TOO_MANY_REQUESTS);
982
983 let r: HttpResponse =
984 ErrorRequestHeaderFieldsTooLarge::<_, DefaultError>("err").into();
985 assert_eq!(r.status(), StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE);
986
987 let r: HttpResponse =
988 ErrorUnavailableForLegalReasons::<_, DefaultError>("err").into();
989 assert_eq!(r.status(), StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS);
990
991 let r: HttpResponse = ErrorInternalServerError::<_, DefaultError>("err").into();
992 assert_eq!(r.status(), StatusCode::INTERNAL_SERVER_ERROR);
993
994 let r: HttpResponse = ErrorNotImplemented::<_, DefaultError>("err").into();
995 assert_eq!(r.status(), StatusCode::NOT_IMPLEMENTED);
996
997 let r: HttpResponse = ErrorBadGateway::<_, DefaultError>("err").into();
998 assert_eq!(r.status(), StatusCode::BAD_GATEWAY);
999
1000 let r: HttpResponse = ErrorServiceUnavailable::<_, DefaultError>("err").into();
1001 assert_eq!(r.status(), StatusCode::SERVICE_UNAVAILABLE);
1002
1003 let r: HttpResponse = ErrorGatewayTimeout::<_, DefaultError>("err").into();
1004 assert_eq!(r.status(), StatusCode::GATEWAY_TIMEOUT);
1005
1006 let r: HttpResponse = ErrorHttpVersionNotSupported::<_, DefaultError>("err").into();
1007 assert_eq!(r.status(), StatusCode::HTTP_VERSION_NOT_SUPPORTED);
1008
1009 let r: HttpResponse = ErrorVariantAlsoNegotiates::<_, DefaultError>("err").into();
1010 assert_eq!(r.status(), StatusCode::VARIANT_ALSO_NEGOTIATES);
1011
1012 let r: HttpResponse = ErrorInsufficientStorage::<_, DefaultError>("err").into();
1013 assert_eq!(r.status(), StatusCode::INSUFFICIENT_STORAGE);
1014
1015 let r: HttpResponse = ErrorLoopDetected::<_, DefaultError>("err").into();
1016 assert_eq!(r.status(), StatusCode::LOOP_DETECTED);
1017
1018 let r: HttpResponse = ErrorNotExtended::<_, DefaultError>("err").into();
1019 assert_eq!(r.status(), StatusCode::NOT_EXTENDED);
1020
1021 let r: HttpResponse =
1022 ErrorNetworkAuthenticationRequired::<_, DefaultError>("err").into();
1023 assert_eq!(r.status(), StatusCode::NETWORK_AUTHENTICATION_REQUIRED);
1024 }
1025}