pub struct ErrorHandlers<B> { /* private fields */ }
Expand description
Middleware for registering custom status code based error handlers.
Register handlers with the ErrorHandlers::handler()
method to register a custom error handler
for a given status code. Handlers can modify existing responses or create completely new ones.
To register a default handler, use the ErrorHandlers::default_handler()
method. This
handler will be used only if a response has an error status code (400-599) that isn’t covered by
a more specific handler (set with the handler()
method). See examples
below.
To register a default for only client errors (400-499) or only server errors (500-599), use the
ErrorHandlers::default_handler_client()
and ErrorHandlers::default_handler_server()
methods, respectively.
Any response with a status code that isn’t covered by a specific handler or a default handler will pass by unchanged by this middleware.
§Examples
Adding a header:
use actix_web::{
dev::ServiceResponse,
http::{header, StatusCode},
middleware::{ErrorHandlerResponse, ErrorHandlers},
web, App, HttpResponse, Result,
};
fn add_error_header<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
res.response_mut().headers_mut().insert(
header::CONTENT_TYPE,
header::HeaderValue::from_static("Error"),
);
// body is unchanged, map to "left" slot
Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
}
let app = App::new()
.wrap(ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, add_error_header))
.service(web::resource("/").route(web::get().to(HttpResponse::InternalServerError)));
Modifying response body:
use actix_web::{
dev::ServiceResponse,
http::{header, StatusCode},
middleware::{ErrorHandlerResponse, ErrorHandlers},
web, App, HttpResponse, Result,
};
fn add_error_body<B>(res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
// split service response into request and response components
let (req, res) = res.into_parts();
// set body of response to modified body
let res = res.set_body("An error occurred.");
// modified bodies need to be boxed and placed in the "right" slot
let res = ServiceResponse::new(req, res)
.map_into_boxed_body()
.map_into_right_body();
Ok(ErrorHandlerResponse::Response(res))
}
let app = App::new()
.wrap(ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, add_error_body))
.service(web::resource("/").route(web::get().to(HttpResponse::InternalServerError)));
Registering default handler:
fn add_error_header<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
res.response_mut().headers_mut().insert(
header::CONTENT_TYPE,
header::HeaderValue::from_static("Error"),
);
// body is unchanged, map to "left" slot
Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
}
fn handle_bad_request<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
res.response_mut().headers_mut().insert(
header::CONTENT_TYPE,
header::HeaderValue::from_static("Bad Request Error"),
);
// body is unchanged, map to "left" slot
Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
}
// Bad Request errors will hit `handle_bad_request()`, while all other errors will hit
// `add_error_header()`. The order in which the methods are called is not meaningful.
let app = App::new()
.wrap(
ErrorHandlers::new()
.default_handler(add_error_header)
.handler(StatusCode::BAD_REQUEST, handle_bad_request)
)
.service(web::resource("/").route(web::get().to(HttpResponse::InternalServerError)));
You can set default handlers for all client (4xx) or all server (5xx) errors:
// Bad request errors will hit `handle_bad_request()`, other client errors will hit
// `add_error_header()`, and server errors will pass through unchanged
let app = App::new()
.wrap(
ErrorHandlers::new()
.default_handler_client(add_error_header) // or .default_handler_server
.handler(StatusCode::BAD_REQUEST, handle_bad_request)
)
.service(web::resource("/").route(web::get().to(HttpResponse::InternalServerError)));
Implementations§
source§impl<B> ErrorHandlers<B>
impl<B> ErrorHandlers<B>
sourcepub fn handler<F>(self, status: StatusCode, handler: F) -> Self
pub fn handler<F>(self, status: StatusCode, handler: F) -> Self
Register error handler for specified status code.
sourcepub fn default_handler<F>(self, handler: F) -> Self
pub fn default_handler<F>(self, handler: F) -> Self
Register a default error handler.
Any request with a status code that hasn’t been given a specific other handler (by calling
.handler()
) will fall back on this.
Note that this will overwrite any default handlers previously set by calling
default_handler_client()
or .default_handler_server()
, but not any set by calling
.handler()
.
sourcepub fn default_handler_client<F>(self, handler: F) -> Self
pub fn default_handler_client<F>(self, handler: F) -> Self
Register a handler on which to fall back for client error status codes (400-499).
sourcepub fn default_handler_server<F>(self, handler: F) -> Self
pub fn default_handler_server<F>(self, handler: F) -> Self
Register a handler on which to fall back for server error status codes (500-599).
Trait Implementations§
source§impl<B> Default for ErrorHandlers<B>
impl<B> Default for ErrorHandlers<B>
source§impl<S, B> Transform<S, ServiceRequest> for ErrorHandlers<B>where
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
S::Future: 'static,
B: 'static,
impl<S, B> Transform<S, ServiceRequest> for ErrorHandlers<B>where
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
S::Future: 'static,
B: 'static,
source§type Response = ServiceResponse<EitherBody<B>>
type Response = ServiceResponse<EitherBody<B>>
source§type Transform = ErrorHandlersMiddleware<S, B>
type Transform = ErrorHandlersMiddleware<S, B>
TransformService
value created by this factory