1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-28 10:02:38 +01:00
actix-web/guide/src/qs_4_5.md

152 lines
4.2 KiB
Markdown
Raw Normal View History

2017-12-09 00:25:37 +01:00
# Errors
Actix uses [`Error` type](../actix_web/error/struct.Error.html)
and [`ResponseError` trait](../actix_web/error/trait.ResponseError.html)
for handling handler's errors.
Any error that implements `ResponseError` trait can be returned as error value.
*Handler* can return *Result* object, actix by default provides
2018-01-13 20:17:48 +01:00
`Responder` implementation for compatible result object. Here is implementation
2017-12-09 00:25:37 +01:00
definition:
```rust,ignore
2017-12-14 18:43:42 +01:00
impl<T: Responder, E: Into<Error>> Responder for Result<T, E>
2017-12-09 00:25:37 +01:00
```
And any error that implements `ResponseError` can be converted into `Error` object.
For example if *handler* function returns `io::Error`, it would be converted
2018-03-02 04:12:59 +01:00
into `HttpInternalServerError` response. Implementation for `io::Error` is provided
2017-12-09 00:25:37 +01:00
by default.
```rust
# extern crate actix_web;
# use actix_web::*;
use std::io;
fn index(req: HttpRequest) -> io::Result<fs::NamedFile> {
Ok(fs::NamedFile::open("static/index.html")?)
}
#
# fn main() {
# Application::new()
2017-12-09 00:25:37 +01:00
# .resource(r"/a/index.html", |r| r.f(index))
# .finish();
# }
```
## Custom error response
2017-12-21 08:27:30 +01:00
To add support for custom errors, all we need to do is just implement `ResponseError` trait
for custom error. `ResponseError` trait has default implementation
for `error_response()` method, it generates *500* response.
2017-12-09 00:25:37 +01:00
```rust
# extern crate actix_web;
#[macro_use] extern crate failure;
use actix_web::*;
#[derive(Fail, Debug)]
#[fail(display="my error")]
struct MyError {
name: &'static str
}
2017-12-21 08:27:30 +01:00
/// Use default implementation for `error_response()` method
2017-12-09 00:25:37 +01:00
impl error::ResponseError for MyError {}
fn index(req: HttpRequest) -> Result<&'static str, MyError> {
Err(MyError{name: "test"})
}
#
# fn main() {
# Application::new()
2017-12-09 00:25:37 +01:00
# .resource(r"/a/index.html", |r| r.f(index))
# .finish();
# }
```
In this example *index* handler will always return *500* response. But it is easy
2017-12-21 08:27:30 +01:00
to return different responses for different type of errors.
2017-12-09 00:25:37 +01:00
```rust
# extern crate actix_web;
#[macro_use] extern crate failure;
use actix_web::*;
#[derive(Fail, Debug)]
enum MyError {
#[fail(display="internal error")]
InternalError,
#[fail(display="bad request")]
BadClientData,
#[fail(display="timeout")]
Timeout,
}
impl error::ResponseError for MyError {
fn error_response(&self) -> HttpResponse {
match *self {
MyError::InternalError => HttpResponse::new(
StatusCode::INTERNAL_SERVER_ERROR, Body::Empty),
MyError::BadClientData => HttpResponse::new(
StatusCode::BAD_REQUEST, Body::Empty),
MyError::Timeout => HttpResponse::new(
StatusCode::GATEWAY_TIMEOUT, Body::Empty),
}
}
}
fn index(req: HttpRequest) -> Result<&'static str, MyError> {
Err(MyError::BadClientData)
}
#
# fn main() {
# Application::new()
2017-12-09 00:25:37 +01:00
# .resource(r"/a/index.html", |r| r.f(index))
# .finish();
# }
```
## Error helpers
Actix provides set of error helper types. It is possible to use them to generate
2018-03-22 05:02:04 +01:00
specific error responses. We can use helper types for first example with custom error.
2017-12-09 00:25:37 +01:00
```rust
# extern crate actix_web;
#[macro_use] extern crate failure;
use actix_web::*;
2018-01-21 07:02:42 +01:00
#[derive(Debug)]
2017-12-09 00:25:37 +01:00
struct MyError {
name: &'static str
}
fn index(req: HttpRequest) -> Result<&'static str> {
let result: Result<&'static str, MyError> = Err(MyError{name: "test"});
2018-03-22 05:02:04 +01:00
Ok(result.map_err(|e| error::ErrorBadRequest(e))?)
2017-12-09 00:25:37 +01:00
}
# fn main() {
# Application::new()
2017-12-09 00:25:37 +01:00
# .resource(r"/a/index.html", |r| r.f(index))
# .finish();
# }
```
2017-12-21 08:27:30 +01:00
In this example *BAD REQUEST* response get generated for `MyError` error.
2018-01-21 05:21:01 +01:00
## Error logging
Actix logs all errors with `WARN` log level. If log level set to `DEBUG`
and `RUST_BACKTRACE` is enabled, backtrace get logged. The Error type uses
cause's error backtrace if available, if the underlying failure does not provide
a backtrace, a new backtrace is constructed pointing to that conversion point
(rather than the origin of the error). This construction only happens if there
is no underlying backtrace; if it does have a backtrace no new backtrace is constructed.
You can enable backtrace and debug logging with following command:
```
>> RUST_BACKTRACE=1 RUST_LOG=actix_web=debug cargo run
```