mirror of https://github.com/fafhrd91/actix-web
add a way to configure error treatment for Query extractor
This commit is contained in:
parent
960274ada8
commit
1b20e288f2
|
@ -200,17 +200,69 @@ impl<T, S> FromRequest<S> for Query<T>
|
||||||
where
|
where
|
||||||
T: de::DeserializeOwned,
|
T: de::DeserializeOwned,
|
||||||
{
|
{
|
||||||
type Config = ();
|
type Config = QueryConfig<S>;
|
||||||
type Result = Result<Self, Error>;
|
type Result = Result<Self, Error>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &HttpRequest<S>, _: &Self::Config) -> Self::Result {
|
fn from_request(req: &HttpRequest<S>, cfg: &Self::Config) -> Self::Result {
|
||||||
|
let req2 = req.clone();
|
||||||
|
let err = Rc::clone(&cfg.ehandler);
|
||||||
serde_urlencoded::from_str::<T>(req.query_string())
|
serde_urlencoded::from_str::<T>(req.query_string())
|
||||||
.map_err(|e| e.into())
|
.map_err(move |e| (*err)(e, &req2))
|
||||||
.map(Query)
|
.map(Query)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Query extractor configuration
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # extern crate actix_web;
|
||||||
|
/// #[macro_use] extern crate serde_derive;
|
||||||
|
/// use actix_web::{error, http, App, HttpResponse, Query, Result};
|
||||||
|
///
|
||||||
|
/// #[derive(Deserialize)]
|
||||||
|
/// struct Info {
|
||||||
|
/// username: String,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// /// deserialize `Info` from request's body, max payload size is 4kb
|
||||||
|
/// fn index(info: Query<Info>) -> Result<String> {
|
||||||
|
/// Ok(format!("Welcome {}!", info.username))
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn main() {
|
||||||
|
/// let app = App::new().resource("/index.html", |r| {
|
||||||
|
/// r.method(http::Method::GET).with_config(index, |cfg| {
|
||||||
|
/// cfg.0.error_handler(|err, req| {
|
||||||
|
/// // <- create custom error response
|
||||||
|
/// error::InternalError::from_response(err, HttpResponse::Conflict().finish()).into()
|
||||||
|
/// });
|
||||||
|
/// })
|
||||||
|
/// });
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub struct QueryConfig<S> {
|
||||||
|
ehandler: Rc<Fn(serde_urlencoded::de::Error, &HttpRequest<S>) -> Error>,
|
||||||
|
}
|
||||||
|
impl<S> QueryConfig<S> {
|
||||||
|
/// Set custom error handler
|
||||||
|
pub fn error_handler<F>(&mut self, f: F) -> &mut Self
|
||||||
|
where
|
||||||
|
F: Fn(serde_urlencoded::de::Error, &HttpRequest<S>) -> Error + 'static,
|
||||||
|
{
|
||||||
|
self.ehandler = Rc::new(f);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> Default for QueryConfig<S> {
|
||||||
|
fn default() -> Self {
|
||||||
|
QueryConfig {
|
||||||
|
ehandler: Rc::new(|e, _| e.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: fmt::Debug> fmt::Debug for Query<T> {
|
impl<T: fmt::Debug> fmt::Debug for Query<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
self.0.fmt(f)
|
self.0.fmt(f)
|
||||||
|
@ -959,7 +1011,7 @@ mod tests {
|
||||||
assert_eq!(s.0, "name");
|
assert_eq!(s.0, "name");
|
||||||
assert_eq!(s.1, "user1");
|
assert_eq!(s.1, "user1");
|
||||||
|
|
||||||
let s = Query::<Id>::from_request(&req, &()).unwrap();
|
let s = Query::<Id>::from_request(&req, &QueryConfig::default()).unwrap();
|
||||||
assert_eq!(s.id, "test");
|
assert_eq!(s.id, "test");
|
||||||
|
|
||||||
let mut router = Router::<()>::default();
|
let mut router = Router::<()>::default();
|
||||||
|
|
Loading…
Reference in New Issue