tweak error pattern

This commit is contained in:
Rob Ede 2020-11-17 22:20:28 +00:00
parent 0c2ae60a2b
commit d9b83cad37
No known key found for this signature in database
GPG Key ID: C2A3B36E841A91E6
4 changed files with 30 additions and 9 deletions

View File

@ -1,4 +1,5 @@
//! Error and Result module //! Error and Result module
pub use actix_http::error::*; pub use actix_http::error::*;
use derive_more::{Display, From}; use derive_more::{Display, From};
use serde_json::error::Error as JsonError; use serde_json::error::Error as JsonError;

View File

@ -106,7 +106,7 @@ pub use crate::responder::Responder;
pub use crate::route::Route; pub use crate::route::Route;
pub use crate::scope::Scope; pub use crate::scope::Scope;
pub use crate::server::HttpServer; pub use crate::server::HttpServer;
pub use crate::types::Either; pub use crate::types::{Either, EitherExtractError};
pub mod dev { pub mod dev {
//! The `actix-web` prelude for library developers //! The `actix-web` prelude for library developers

View File

@ -108,16 +108,17 @@ where
} }
} }
/// A composite error resulting from failure to extract an `Either<A, B>`.
///
/// The implementation of `Into<actix_web::Error>` will return the payload buffering error or the
/// error from the primary extractor. To access the fallback error, use a match clause.
#[derive(Debug)] #[derive(Debug)]
pub enum EitherExtractError<A, B> { pub enum EitherExtractError<A, B> {
/// Error from payload buffering, such as exceeding payload max size limit. /// Error from payload buffering, such as exceeding payload max size limit.
Bytes(Error), Bytes(Error),
/// Error from primary extractor. /// Error from primary extractor.
A(A), Extract(A, B),
/// Error from fallback extractor.
B(B),
} }
impl<A, B> Into<Error> for EitherExtractError<A, B> impl<A, B> Into<Error> for EitherExtractError<A, B>
@ -128,8 +129,7 @@ where
fn into(self) -> Error { fn into(self) -> Error {
match self { match self {
EitherExtractError::Bytes(err) => err, EitherExtractError::Bytes(err) => err,
EitherExtractError::A(err) => err.into(), EitherExtractError::Extract(a_err, _b_err) => a_err.into(),
EitherExtractError::B(err) => err.into(),
} }
} }
} }
@ -179,7 +179,7 @@ where
let mut pl = payload_from_bytes(fallback); let mut pl = payload_from_bytes(fallback);
match B::from_request(&req, &mut pl).await { match B::from_request(&req, &mut pl).await {
Ok(b_data) => return Ok(Either::B(b_data)), 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(); .unwrap_right();
assert_eq!(&payload.as_ref(), &b"!@$%^&*()"); 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::<Either<Form<TestForm>, Json<TestForm>>, Bytes>::from_request(
&req, &mut pl,
)
.await
.unwrap()
.unwrap_left()
.unwrap_right()
.into_inner();
assert_eq!(&form.hello, "world");
}
} }

View File

@ -8,7 +8,7 @@ pub(crate) mod payload;
mod query; mod query;
pub(crate) mod readlines; pub(crate) mod readlines;
pub use self::either::Either; pub use self::either::{Either, EitherExtractError};
pub use self::form::{Form, FormConfig}; pub use self::form::{Form, FormConfig};
pub use self::json::{Json, JsonConfig}; pub use self::json::{Json, JsonConfig};
pub use self::path::{Path, PathConfig}; pub use self::path::{Path, PathConfig};