1
0
mirror of https://github.com/actix/actix-website synced 2024-11-27 18:12:57 +01:00

Errors section is done-ish.

This commit is contained in:
Cameron Dershem 2019-06-24 21:18:30 -04:00
parent 60f4f116cf
commit 6b08c4664b
7 changed files with 77 additions and 35 deletions

View File

@ -6,13 +6,13 @@ weight: 180
# Errors # Errors
Actix uses its own [`actix_web::error::Error`][actixerror] type and Actix-web uses its own [`actix_web::error::Error`][actixerror] type and
[`actix_web::error::ResponseError`][responseerror] trait for error handling [`actix_web::error::ResponseError`][responseerror] trait for error handling
from web handlers. from web handlers.
If a handler returns an `Error` (referring to the [general Rust trait If a handler returns an `Error` (referring to the [general Rust trait
`std::error::Error`][stderror]) in a `Result` that also implements the `std::error::Error`][stderror]) in a `Result` that also implements the
`ResponseError` trait, actix will render that error as an HTTP response. `ResponseError` trait, actix-web will render that error as an HTTP response.
`ResponseError` has a single function called `error_response()` that returns `ResponseError` has a single function called `error_response()` that returns
`HttpResponse`: `HttpResponse`:
@ -30,7 +30,7 @@ A `Responder` coerces compatible `Result`s into HTTP responses:
impl<T: Responder, E: Into<Error>> Responder for Result<T, E> impl<T: Responder, E: Into<Error>> Responder for Result<T, E>
``` ```
`Error` in the code above is actix's error definition, and any errors that `Error` in the code above is actix-web's error definition, and any errors that
implement `ResponseError` can be converted to one automatically. implement `ResponseError` can be converted to one automatically.
Actix-web provides `ResponseError` implementations for some common non-actix Actix-web provides `ResponseError` implementations for some common non-actix
@ -45,8 +45,8 @@ fn index(req: &HttpRequest) -> io::Result<fs::NamedFile> {
} }
``` ```
See [the actix-web API documentation][responseerrorimpls] for a full list of See [the actix-web API documentation][responseerrorimpls] for a full list of foreign
foreign implementations for `ResponseError`. implementations for `ResponseError`.
## An example of a custom error response ## An example of a custom error response
@ -64,15 +64,15 @@ Override `error_response()` to produce more useful results:
# Error helpers # Error helpers
Actix provides a set of error helper functions that are useful for generating Actix-web provides a set of error helper functions that are useful for generating
specific HTTP error codes from other errors. Here we convert `MyError`, which specific HTTP error codes from other errors. Here we convert `MyError`, which
doesn't implement the `ResponseError` trait, to a *400* (bad request) using doesn't implement the `ResponseError` trait, to a *400* (bad request) using
`map_err`: `map_err`:
{{< include-example example="errors" file="helpers.rs" section="helpers" >}} {{< include-example example="errors" file="helpers.rs" section="helpers" >}}
See the [API documentation for actix-web's `error` module][errorhelpers] for a See the [API documentation for actix-web's `error` module][actixerror]
full list of available error helpers. for a full list of available error helpers.
# Compatibility with failure # Compatibility with failure
@ -128,9 +128,9 @@ 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 can ensure that we don't accidentally expose users to errors thrown by
application internals which they weren't meant to see. application internals which they weren't meant to see.
[actixerror]: ../../actix-web/actix_web/error/struct.Error.html [actixerror]: https://docs.rs/actix-web/1.0.2/actix_web/error/struct.Error.html
[errorhelpers]: ../../actix-web/actix_web/error/index.html#functions [errorhelpers]: https://docs.rs/actix-web/1.0.2/actix_web/trait.ResponseError.html
[failure]: https://github.com/rust-lang-nursery/failure [failure]: https://github.com/rust-lang-nursery/failure
[responseerror]: ../../actix-web/actix_web/error/trait.ResponseError.html [responseerror]: https://docs.rs/actix-web/1.0.2/actix_web/error/trait.ResponseError.html
[responseerrorimpls]: ../../actix-web/actix_web/error/trait.ResponseError.html#foreign-impls [responseerrorimpls]: https://docs.rs/actix-web/1.0.2/actix_web/error/trait.ResponseError.html#foreign-impls
[stderror]: https://doc.rust-lang.org/std/error/trait.Error.html [stderror]: https://doc.rust-lang.org/std/error/trait.Error.html

View File

@ -6,3 +6,5 @@ edition = "2018"
[dependencies] [dependencies]
actix-web = "1.0" actix-web = "1.0"
failure = "0.1" failure = "0.1"
env_logger = "0.6"
log = "0.4"

View File

@ -8,11 +8,18 @@ struct MyError {
} }
pub fn index(_req: HttpRequest) -> Result<&'static str> { pub fn index(_req: HttpRequest) -> Result<&'static str> {
let result: Result<&'static str, MyError> = Err(MyError { name: "test" }); let result: Result<&'static str, MyError> = Err(MyError { name: "test error" });
Ok(result.map_err(|e| error::ErrorBadRequest(e.name))?) Ok(result.map_err(|e| error::ErrorBadRequest(e.name))?)
} }
// </helpers> // </helpers>
pub fn main() { pub fn main() {
App::new().route("/", web::get().to(index)); use actix_web::HttpServer;
HttpServer::new(|| App::new().route("/", web::get().to(index)))
.bind("127.0.0.1:8088")
.unwrap()
.run()
.unwrap();
} }

View File

@ -1,9 +1,10 @@
pub mod helpers; pub mod helpers;
pub mod override_error; pub mod override_error;
pub mod recommend_one; pub mod recommend_one;
use actix_web::{web, App}; pub mod recommend_two;
// <response-error> // <response-error>
use actix_web::{error, HttpRequest}; use actix_web::{error, HttpRequest, Result};
use failure::Fail; use failure::Fail;
#[derive(Fail, Debug)] #[derive(Fail, Debug)]
@ -19,6 +20,14 @@ fn index(_req: HttpRequest) -> Result<&'static str, MyError> {
Err(MyError { name: "test" }) Err(MyError { name: "test" })
} }
// </response-error> // </response-error>
pub fn main() { pub fn main() {
App::new().route("/", web::get().to(index)); // use actix_web::{web, App, HttpServer};
// HttpServer::new(|| App::new().route("/", web::get().to(index)))
// .bind("127.0.0.1:8088")
// .unwrap()
// .run()
// .unwrap();
recommend_two::main();
} }

View File

@ -29,12 +29,6 @@ fn index(_req: HttpRequest) -> Result<&'static str, MyError> {
Err(MyError::BadClientData) Err(MyError::BadClientData)
} }
// </override> // </override>
pub fn main() {
App::new()
.route("/", web::get().to(index))
.route("/e2", web::get().to(error2))
.route("/e3", web::get().to(error3));
}
fn error2(_req: HttpRequest) -> Result<&'static str, MyError> { fn error2(_req: HttpRequest) -> Result<&'static str, MyError> {
Err(MyError::InternalError) Err(MyError::InternalError)
@ -43,3 +37,18 @@ fn error2(_req: HttpRequest) -> Result<&'static str, MyError> {
fn error3(_req: HttpRequest) -> Result<&'static str, MyError> { fn error3(_req: HttpRequest) -> Result<&'static str, MyError> {
Err(MyError::Timeout) Err(MyError::Timeout)
} }
pub fn main() {
use actix_web::HttpServer;
HttpServer::new(|| {
App::new()
.route("/", web::get().to(index))
.route("/e2", web::get().to(error2))
.route("/e3", web::get().to(error3))
})
.bind("127.0.0.1:8088")
.unwrap()
.run()
.unwrap();
}

View File

@ -1,4 +1,3 @@
use actix_web::{web, App, HttpRequest};
// <recommend-one> // <recommend-one>
use actix_web::{error, http, HttpResponse}; use actix_web::{error, http, HttpResponse};
use failure::Fail; use failure::Fail;
@ -19,12 +18,18 @@ impl error::ResponseError for UserError {
} }
} }
// </recommend-one> // </recommend-one>
pub fn main() { fn index() -> Result<&'static str, UserError> {
App::new().route("/", web::get().to(index));
}
fn index(_req: HttpRequest) -> Result<&'static str, UserError> {
Err(UserError::ValidationError { Err(UserError::ValidationError {
field: "bad stuff".to_string(), field: "bad stuff".to_string(),
}) })
} }
pub fn main() {
use actix_web::{web, App, HttpServer};
HttpServer::new(|| App::new().route("/", web::get().to(index)))
.bind("127.0.0.1:8088")
.unwrap()
.run()
.unwrap();
}

View File

@ -1,6 +1,5 @@
use actix_web::App;
// <recommend-two> // <recommend-two>
use actix_web::{error, fs, http, HttpRequest, HttpResponse}; use actix_web::{error, http, HttpResponse};
use failure::Fail; use failure::Fail;
#[derive(Fail, Debug)] #[derive(Fail, Debug)]
@ -19,11 +18,22 @@ impl error::ResponseError for UserError {
} }
} }
fn index(_req: HttpRequest) -> Result<&'static str, UserError> { fn index() -> Result<&'static str, UserError> {
fs::NamedFile::open("static/index.html").map_err(|_e| UserError::InternalError)?; do_thing_that_failes().map_err(|_e| UserError::InternalError)?;
Ok("success!") Ok("success!")
} }
// </recommend-two> // </recommend-two>
pub fn main() {
App::new().route("/", web::get().to(index)); fn do_thing_that_failes() -> Result<(), std::io::Error> {
Err(std::io::Error::new(std::io::ErrorKind::Other, "some error"))
}
pub fn main() {
use actix_web::{web, App, HttpServer};
HttpServer::new(|| App::new().route("/", web::get().to(index)))
.bind("127.0.0.1:8088")
.unwrap()
.run()
.unwrap();
} }