diff --git a/src/error.rs b/src/error.rs index 659ba05fd..60af8fa11 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,5 @@ //! Error and Result module + pub use actix_http::error::*; use derive_more::{Display, From}; use serde_json::error::Error as JsonError; diff --git a/src/lib.rs b/src/lib.rs index 8f1cbce89..13e02c098 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -106,7 +106,7 @@ pub use crate::responder::Responder; pub use crate::route::Route; pub use crate::scope::Scope; pub use crate::server::HttpServer; -pub use crate::types::Either; +pub use crate::types::{Either, EitherExtractError}; pub mod dev { //! The `actix-web` prelude for library developers diff --git a/src/types/either.rs b/src/types/either.rs index bfd5cbbf0..9f1d81a0b 100644 --- a/src/types/either.rs +++ b/src/types/either.rs @@ -108,16 +108,17 @@ where } } +/// A composite error resulting from failure to extract an `Either`. +/// +/// The implementation of `Into` will return the payload buffering error or the +/// error from the primary extractor. To access the fallback error, use a match clause. #[derive(Debug)] pub enum EitherExtractError { /// Error from payload buffering, such as exceeding payload max size limit. Bytes(Error), /// Error from primary extractor. - A(A), - - /// Error from fallback extractor. - B(B), + Extract(A, B), } impl Into for EitherExtractError @@ -128,8 +129,7 @@ where fn into(self) -> Error { match self { EitherExtractError::Bytes(err) => err, - EitherExtractError::A(err) => err.into(), - EitherExtractError::B(err) => err.into(), + EitherExtractError::Extract(a_err, _b_err) => a_err.into(), } } } @@ -179,7 +179,7 @@ where let mut pl = payload_from_bytes(fallback); match B::from_request(&req, &mut pl).await { Ok(b_data) => return Ok(Either::B(b_data)), - Err(_b_err) => Err(EitherExtractError::A(a_err)), + Err(b_err) => Err(EitherExtractError::Extract(a_err, b_err)), } } @@ -251,4 +251,24 @@ mod tests { .unwrap_right(); assert_eq!(&payload.as_ref(), &b"!@$%^&*()"); } + + #[actix_rt::test] + async fn test_either_extract_recursive_fallback_inner() { + let (req, mut pl) = TestRequest::default() + .set_json(&TestForm { + hello: "world".to_owned(), + }) + .to_http_parts(); + + let form = + Either::, Json>, Bytes>::from_request( + &req, &mut pl, + ) + .await + .unwrap() + .unwrap_left() + .unwrap_right() + .into_inner(); + assert_eq!(&form.hello, "world"); + } } diff --git a/src/types/mod.rs b/src/types/mod.rs index e220f1b1a..cedf86dd2 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -8,7 +8,7 @@ pub(crate) mod payload; mod query; pub(crate) mod readlines; -pub use self::either::Either; +pub use self::either::{Either, EitherExtractError}; pub use self::form::{Form, FormConfig}; pub use self::json::{Json, JsonConfig}; pub use self::path::{Path, PathConfig};