2018-05-22 23:15:08 +02:00
---
title: Errors
menu: docs_advanced
weight: 180
---
# Errors
2019-06-25 03:18:30 +02:00
Actix-web uses its own [`actix_web::error::Error`][actixerror] type and
2018-05-22 23:15:08 +02:00
[`actix_web::error::ResponseError`][responseerror] trait for error handling
from web handlers.
If a handler returns an `Error` (referring to the [general Rust trait
`std::error::Error` ][stderror]) in a `Result` that also implements the
2020-01-03 05:10:24 +01:00
`ResponseError` trait, actix-web will render that error as an HTTP response with it's corresponding [`actix_web::http::StatusCode`][status_code]. Internal server error is generated by default:
2018-05-22 23:15:08 +02:00
```rust
2020-01-03 05:10:24 +01:00
pub trait ResponseError {
fn error_response(& self) -> HttpResponse;
fn status_code(& self) -> StatusCode;
2018-05-22 23:15:08 +02:00
}
```
A `Responder` coerces compatible `Result` s into HTTP responses:
```rust
impl< T: Responder , E: Into < Error > > Responder for Result< T , E >
```
2019-06-25 03:18:30 +02:00
`Error` in the code above is actix-web's error definition, and any errors that
2018-05-22 23:15:08 +02:00
implement `ResponseError` can be converted to one automatically.
Actix-web provides `ResponseError` implementations for some common non-actix
errors. For example, if a handler responds with an `io::Error` , that error is
converted into an `HttpInternalServerError` :
```rust
use std::io;
2019-06-28 19:31:30 +02:00
fn index(_req: HttpRequest) -> io::Result< fs::NamedFile > {
2018-05-22 23:15:08 +02:00
Ok(fs::NamedFile::open("static/index.html")?)
}
```
2019-06-25 03:18:30 +02:00
See [the actix-web API documentation][responseerrorimpls] for a full list of foreign
implementations for `ResponseError` .
2018-05-22 23:15:08 +02:00
## An example of a custom error response
Here's an example implementation for `ResponseError` :
2019-06-17 19:46:21 +02:00
{{< include-example example = "errors" file = "main.rs" section = "response-error" > }}
2018-05-22 23:15:08 +02:00
`ResponseError` has a default implementation for `error_response()` that will
2020-01-03 05:10:24 +01:00
render a _500_ (internal server error), and that's what will happen when the
2018-05-22 23:15:08 +02:00
`index` handler executes above.
Override `error_response()` to produce more useful results:
2019-06-17 19:46:21 +02:00
{{< include-example example = "errors" file = "override_error.rs" section = "override" > }}
2018-05-22 23:15:08 +02:00
# Error helpers
2019-06-25 03:18:30 +02:00
Actix-web provides a set of error helper functions that are useful for generating
2018-05-22 23:15:08 +02:00
specific HTTP error codes from other errors. Here we convert `MyError` , which
2020-01-03 05:10:24 +01:00
doesn't implement the `ResponseError` trait, to a _400_ (bad request) using
2018-05-22 23:15:08 +02:00
`map_err` :
2019-06-17 19:46:21 +02:00
{{< include-example example = "errors" file = "helpers.rs" section = "helpers" > }}
2018-05-22 23:15:08 +02:00
2019-06-25 03:18:30 +02:00
See the [API documentation for actix-web's `error` module][actixerror]
for a full list of available error helpers.
2018-05-22 23:15:08 +02:00
# Compatibility with failure
Actix-web provides automatic compatibility with the [failure] library so that
errors deriving `fail` will be converted automatically to an actix error. Keep
2020-01-03 05:10:24 +01:00
in mind that those errors will render with the default _500_ status code unless you
2018-05-22 23:15:08 +02:00
also provide your own `error_response()` implementation for them.
# Error logging
Actix logs all errors at the `WARN` log level. If an application's log level is
set to `DEBUG` and `RUST_BACKTRACE` is enabled, the backtrace is also logged.
These are configurable with environmental variables:
```
>> RUST_BACKTRACE=1 RUST_LOG=actix_web=debug cargo run
```
The `Error` type uses the cause's error backtrace if available. If the
underlying failure does not provide a backtrace, a new backtrace is constructed
pointing to the point where the conversion occurred (rather than the origin of
the error).
# Recommended practices in error handling
It might be useful to think about dividing the errors an application produces
into two broad groups: those which are intended to be be user-facing, and those
which are not.
An example of the former is that I might use failure to specify a `UserError`
enum which encapsulates a `ValidationError` to return whenever a user sends bad
input:
2019-06-17 19:46:21 +02:00
{{< include-example example = "errors" file = "recommend_one.rs" section = "recommend-one" > }}
2018-05-22 23:15:08 +02:00
This will behave exactly as intended because the error message defined with
`display` is written with the explicit intent to be read by a user.
However, sending back an error's message isn't desirable for all errors --
there are many failures that occur in a server environment where we'd probably
want the specifics to be hidden from the user. For example, if a database goes
down and client libraries start producing connect timeout errors, or if an HTML
template was improperly formatted and errors when rendered. In these cases, it
might be preferable to map the errors to a generic error suitable for user
consumption.
Here's an example that maps an internal error to a user-facing `InternalError`
with a custom message:
2019-06-17 19:46:21 +02:00
{{< include-example example = "errors" file = "recommend_two.rs" section = "recommend-two" > }}
2018-05-22 23:15:08 +02:00
By dividing errors into those which are user facing and those which are not, we
can ensure that we don't accidentally expose users to errors thrown by
application internals which they weren't meant to see.
2019-06-28 20:50:15 +02:00
# Error Logging
This is a basic example using `middleware::Logger` :
{{< include-example example = "errors" file = "logging.rs" section = "logging" > }}
2019-12-28 16:38:07 +01:00
[actixerror]: https://docs.rs/actix-web/2/actix_web/error/struct.Error.html
[errorhelpers]: https://docs.rs/actix-web/2/actix_web/trait.ResponseError.html
2018-05-22 23:15:08 +02:00
[failure]: https://github.com/rust-lang-nursery/failure
2019-12-28 16:38:07 +01:00
[responseerror]: https://docs.rs/actix-web/2/actix_web/error/trait.ResponseError.html
[responseerrorimpls]: https://docs.rs/actix-web/2/actix_web/error/trait.ResponseError.html#foreign-impls
2018-05-22 23:15:08 +02:00
[stderror]: https://doc.rust-lang.org/std/error/trait.Error.html
2020-01-03 05:10:24 +01:00
[status_code]: https://docs.rs/actix-web/2.0.0/actix_web/http/struct.StatusCode.html