diff --git a/src/app.rs b/src/app.rs index 29dd1ab60..54b5ded25 100644 --- a/src/app.rs +++ b/src/app.rs @@ -3,8 +3,6 @@ use std::marker::PhantomData; use std::rc::Rc; use actix_http::body::{Body, MessageBody}; -use actix_http::PayloadStream; -use actix_router::ResourceDef; use actix_server_config::ServerConfig; use actix_service::boxed::{self, BoxedNewService}; use actix_service::{ @@ -14,6 +12,8 @@ use futures::IntoFuture; use crate::app_service::{AppChain, AppEntry, AppInit, AppRouting, AppRoutingFactory}; use crate::config::{AppConfig, AppConfigInner}; +use crate::dev::{PayloadStream, ResourceDef}; +use crate::error::Error; use crate::resource::Resource; use crate::route::Route; use crate::service::{ @@ -22,7 +22,8 @@ use crate::service::{ }; use crate::state::{State, StateFactory}; -type HttpNewService
= BoxedNewService<(), ServiceRequest
, ServiceResponse, (), ()>; +type HttpNewService
= + BoxedNewService<(), ServiceRequest
, ServiceResponse, Error, ()>; /// Application builder - structure that follows the builder pattern /// for building application instances. @@ -55,7 +56,7 @@ where T: NewService< Request = ServiceRequest, Response = ServiceRequest
, - Error = (), + Error = Error, InitError = (), >, { @@ -118,7 +119,7 @@ where impl NewService< Request = ServiceRequest
, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, > @@ -127,7 +128,7 @@ where AppRouting
, Request = ServiceRequest
,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
>,
F: IntoTransform ,
Response = ServiceRequest ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
>,
{
@@ -324,7 +325,7 @@ where
impl NewService<
Request = ServiceRequest ,
Response = ServiceResponse ,
Response = ServiceResponse ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
> + 'static,
{
@@ -415,13 +416,13 @@ where
T: NewService<
Request = ServiceRequest ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
>,
C: NewService<
Request = ServiceRequest,
Response = ServiceRequest ,
- Error = (),
+ Error = Error,
InitError = (),
>,
{
diff --git a/src/app_service.rs b/src/app_service.rs
index 75e4b3164..c59b80bcc 100644
--- a/src/app_service.rs
+++ b/src/app_service.rs
@@ -11,15 +11,17 @@ use futures::future::{ok, Either, FutureResult};
use futures::{Async, Future, Poll};
use crate::config::{AppConfig, ServiceConfig};
+use crate::error::Error;
use crate::guard::Guard;
use crate::rmap::ResourceMap;
use crate::service::{ServiceFactory, ServiceRequest, ServiceResponse};
use crate::state::{StateFactory, StateFactoryResult};
type Guards = Vec = BoxedService = BoxedNewService<(), ServiceRequest , ServiceResponse, (), ()>;
-type BoxedResponse = Box = BoxedService =
+ BoxedNewService<(), ServiceRequest , ServiceResponse, Error, ()>;
+type BoxedResponse = Box ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
>,
{
@@ -48,13 +50,13 @@ where
C: NewService<
Request = ServiceRequest,
Response = ServiceRequest ,
- Error = (),
+ Error = Error,
InitError = (),
>,
T: NewService<
Request = ServiceRequest ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
>,
{
@@ -147,13 +149,13 @@ where
C: NewService<
Request = ServiceRequest,
Response = ServiceRequest ,
- Error = (),
+ Error = Error,
InitError = (),
>,
T: NewService<
Request = ServiceRequest ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
>,
{
@@ -201,7 +203,7 @@ where
/// Service to convert `Request` to a `ServiceRequest ;
@@ -240,7 +242,7 @@ pub struct AppRoutingFactory {
impl {
type Request = ServiceRequest ;
type Response = ServiceResponse;
- type Error = ();
+ type Error = Error;
type InitError = ();
type Service = AppRouting ;
type Future = AppRoutingFactoryResponse ;
@@ -350,7 +352,7 @@ pub struct AppRouting {
impl Service for AppRouting {
type Request = ServiceRequest ;
type Response = ServiceResponse;
- type Error = ();
+ type Error = Error;
type Future = Either AppEntry {
impl {
type Request = ServiceRequest ;
type Response = ServiceResponse;
- type Error = ();
+ type Error = Error;
type InitError = ();
type Service = AppRouting ;
type Future = AppRoutingFactoryResponse ;
@@ -414,7 +416,7 @@ pub struct AppChain;
impl NewService for AppChain {
type Request = ServiceRequest;
type Response = ServiceRequest;
- type Error = ();
+ type Error = Error;
type InitError = ();
type Service = AppChain;
type Future = FutureResult =
- boxed::BoxedNewService<(), ServiceRequest , ServiceResponse, (), ()>;
+ boxed::BoxedNewService<(), ServiceRequest , ServiceResponse, Error, ()>;
/// Application configuration
pub struct ServiceConfig {
@@ -84,7 +85,7 @@ impl {
S: NewService<
Request = ServiceRequest ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
> + 'static,
{
diff --git a/src/handler.rs b/src/handler.rs
index 876456510..4ff3193c8 100644
--- a/src/handler.rs
+++ b/src/handler.rs
@@ -193,7 +193,7 @@ where
{
type Request = (T, HttpRequest);
type Response = ServiceResponse;
- type Error = ();
+ type Error = Error;
type InitError = ();
type Service = AsyncHandlerService ,
+ Response = ServiceResponse,
+ Error = Error,
+ >,
+ S::Future: 'static,
+ S::Error: 'static,
+ B: 'static,
+{
+ type Request = ServiceRequest ;
+ type Response = ServiceResponse;
+ type Error = Error;
+ type InitError = ();
+ type Transform = ErrorHandlersMiddleware ,
+ Response = ServiceResponse,
+ Error = Error,
+ >,
+ S::Future: 'static,
+ S::Error: 'static,
+ B: 'static,
+{
+ type Request = ServiceRequest ;
+ type Response = ServiceResponse;
+ type Error = Error;
+ type Future = Box ) -> Self::Future {
+ let handlers = self.handlers.clone();
+
+ Box::new(self.service.call(req).and_then(move |res| {
+ if let Some(handler) = handlers.get(&res.status()) {
+ match handler(res) {
+ Ok(ErrorHandlerResponse::Response(res)) => Either::A(ok(res)),
+ Ok(ErrorHandlerResponse::Future(fut)) => Either::B(fut),
+ Err(e) => Either::A(err(e)),
+ }
+ } else {
+ Either::A(ok(res))
+ }
+ }))
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use actix_service::FnService;
+ use futures::future::ok;
+
+ use super::*;
+ use crate::http::{header::CONTENT_TYPE, HeaderValue, StatusCode};
+ use crate::test::{self, TestRequest};
+ use crate::HttpResponse;
+
+ fn render_500(mut res: ServiceResponse) -> Result = BoxedService = BoxedNewService<(), ServiceRequest , ServiceResponse, (), ()>;
+type HttpService = BoxedService =
+ BoxedNewService<(), ServiceRequest , ServiceResponse, Error, ()>;
/// *Resource* is an entry in route table which corresponds to requested URL.
///
@@ -70,7 +71,7 @@ where
T: NewService<
Request = ServiceRequest ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
>,
{
@@ -232,7 +233,7 @@ where
impl NewService<
Request = ServiceRequest ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
>,
>
@@ -241,7 +242,7 @@ where
T::Service,
Request = ServiceRequest ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
>,
F: IntoTransform ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
> + 'static,
{
// create and configure default resource
@@ -284,7 +285,7 @@ where
T: NewService<
Request = ServiceRequest ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
> + 'static,
{
@@ -314,7 +315,7 @@ where
T: NewService<
Request = ServiceRequest ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
>,
{
@@ -336,7 +337,7 @@ pub struct ResourceFactory {
impl {
type Request = ServiceRequest ;
type Response = ServiceResponse;
- type Error = ();
+ type Error = Error;
type InitError = ();
type Service = ResourceService ;
type Future = CreateResourceService ;
@@ -427,9 +428,9 @@ pub struct ResourceService {
impl Service for ResourceService {
type Request = ServiceRequest ;
type Response = ServiceResponse;
- type Error = ();
+ type Error = Error;
type Future = Either<
- Box ResourceEndpoint {
impl {
type Request = ServiceRequest ;
type Response = ServiceResponse;
- type Error = ();
+ type Error = Error;
type InitError = ();
type Service = ResourceService ;
type Future = CreateResourceService ;
diff --git a/src/route.rs b/src/route.rs
index 1955a81ad..707da3d85 100644
--- a/src/route.rs
+++ b/src/route.rs
@@ -17,8 +17,8 @@ type BoxedRouteService {
impl NewService for Route {
type Request = ServiceRequest ;
type Response = ServiceResponse;
- type Error = ();
+ type Error = Error;
type InitError = ();
type Service = RouteService ;
type Future = CreateRouteService ;
@@ -129,7 +129,7 @@ impl RouteService {
impl Service for RouteService {
type Request = ServiceRequest ;
type Response = ServiceResponse;
- type Error = ();
+ type Error = Error;
type Future = Box {
// T: NewService<
// Request = HandlerRequest ;
type Response = ServiceResponse;
- type Error = ();
+ type Error = Error;
type InitError = ();
type Service = BoxedRouteService ;
type Response = ServiceResponse;
- type Error = ();
+ type Error = Error;
type Future = Box ) -> Self::Future {
diff --git a/src/scope.rs b/src/scope.rs
index 3b5061737..9f5b650cd 100644
--- a/src/scope.rs
+++ b/src/scope.rs
@@ -11,6 +11,7 @@ use futures::future::{ok, Either, Future, FutureResult};
use futures::{Async, Poll};
use crate::dev::{HttpServiceFactory, ServiceConfig};
+use crate::error::Error;
use crate::guard::Guard;
use crate::resource::Resource;
use crate::rmap::ResourceMap;
@@ -20,9 +21,10 @@ use crate::service::{
};
type Guards = Vec = BoxedService = BoxedNewService<(), ServiceRequest , ServiceResponse, (), ()>;
-type BoxedResponse = Box = BoxedService =
+ BoxedNewService<(), ServiceRequest , ServiceResponse, Error, ()>;
+type BoxedResponse = Box ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
>,
{
@@ -176,7 +178,7 @@ where
U: NewService<
Request = ServiceRequest ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
> + 'static,
{
@@ -201,7 +203,7 @@ where
impl NewService<
Request = ServiceRequest ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
>,
>
@@ -210,7 +212,7 @@ where
T::Service,
Request = ServiceRequest ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
>,
F: IntoTransform ,
Response = ServiceResponse,
- Error = (),
+ Error = Error,
InitError = (),
> + 'static,
{
@@ -290,7 +292,7 @@ pub struct ScopeFactory {
impl {
type Request = ServiceRequest ;
type Response = ServiceResponse;
- type Error = ();
+ type Error = Error;
type InitError = ();
type Service = ScopeService ;
type Future = ScopeFactoryResponse ;
@@ -406,7 +408,7 @@ pub struct ScopeService {
impl Service for ScopeService {
type Request = ServiceRequest ;
type Response = ServiceResponse;
- type Error = ();
+ type Error = Error;
type Future = Either ScopeEndpoint {
impl {
type Request = ServiceRequest ;
type Response = ServiceResponse;
- type Error = ();
+ type Error = Error;
type InitError = ();
type Service = ScopeService ;
type Future = ScopeFactoryResponse ;
diff --git a/src/service.rs b/src/service.rs
index 08330282d..e907a1abc 100644
--- a/src/service.rs
+++ b/src/service.rs
@@ -340,6 +340,12 @@ impl ServiceResponse {
Self::from_err(err, self.request)
}
+ /// Create service response
+ #[inline]
+ pub fn into_response`.
/// It also executes state factories.
@@ -29,7 +31,7 @@ where
T: NewService<
Request = ServiceRequest`
pub struct AppInitService Transform for ErrorHandlers
+where
+ S: Service<
+ Request = ServiceRequest;
+ type Future = FutureResult {
+ service: S,
+ handlers: Rc Service for ErrorHandlersMiddleware
+where
+ S: Service<
+ Request = ServiceRequest,
// Response = HandlerRequest,
- // InitError = (),
+ // InitError = Error,
// >,
// {
// RouteServiceBuilder {
@@ -372,7 +372,7 @@ where
{
type Request = ServiceRequest