mirror of
https://github.com/actix/examples
synced 2024-11-23 22:41:07 +01:00
added error_handling example
This commit is contained in:
parent
7262de4917
commit
8f62837614
@ -8,6 +8,7 @@ members = [
|
||||
"cookie-auth-full",
|
||||
"cookie-session",
|
||||
"diesel",
|
||||
"error_handling",
|
||||
"form",
|
||||
"hello-world",
|
||||
"http-proxy",
|
||||
|
2
error_handling/.gitignore
vendored
Normal file
2
error_handling/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/target
|
||||
**/*.rs.bk
|
12
error_handling/Cargo.toml
Normal file
12
error_handling/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "error_handling"
|
||||
version = "0.1.0"
|
||||
authors = ["dowwie <dkcdkg@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
actix = "0.7.3"
|
||||
actix-web = "0.7.3"
|
||||
failure = "0.1.2"
|
||||
futures = "0.1.23"
|
||||
rand = "0.5.4"
|
||||
env_logger = "0.5.12"
|
1
error_handling/README.md
Normal file
1
error_handling/README.md
Normal file
@ -0,0 +1 @@
|
||||
This project illustrates custom error propagation through futures in actix-web
|
139
error_handling/src/main.rs
Normal file
139
error_handling/src/main.rs
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
The goal of this example is to show how to propagate a custom error type, derived
|
||||
from the Fail trait, to a web handler that will evaluate the type of error that
|
||||
was raised and return an appropriate HTTPResponse.
|
||||
|
||||
This example uses a 50/50 chance of returning 200 Ok, otherwise one of four possible
|
||||
http errors will be chosen, each with an equal chance of being selected:
|
||||
1. 403 Forbidden
|
||||
2. 401 Unauthorized
|
||||
3. 500 InternalServerError
|
||||
4. 400 BadRequest
|
||||
|
||||
*/
|
||||
|
||||
|
||||
extern crate actix;
|
||||
extern crate actix_web;
|
||||
extern crate env_logger;
|
||||
#[macro_use] extern crate failure;
|
||||
extern crate futures;
|
||||
extern crate rand;
|
||||
|
||||
|
||||
use actix_web::{
|
||||
http::Method, server, App, AsyncResponder, Error as ActixWebError,
|
||||
HttpResponse, HttpRequest
|
||||
};
|
||||
use failure::Error as FailureError; // naming it clearly for illustration purposes
|
||||
use futures::{
|
||||
future::{
|
||||
ok as fut_ok,
|
||||
err as fut_err
|
||||
},
|
||||
Future
|
||||
};
|
||||
use rand::{thread_rng, Rng, distributions::{Distribution, Standard}};
|
||||
|
||||
|
||||
|
||||
#[derive(Fail, Debug)]
|
||||
pub enum CustomError {
|
||||
#[fail(display = "Custom Error 1")]
|
||||
CustomOne,
|
||||
#[fail(display = "Custom Error 2")]
|
||||
CustomTwo,
|
||||
#[fail(display = "Custom Error 3")]
|
||||
CustomThree,
|
||||
#[fail(display = "Custom Error 4")]
|
||||
CustomFour
|
||||
}
|
||||
|
||||
|
||||
impl Distribution<CustomError> for Standard {
|
||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> CustomError {
|
||||
match rng.gen_range(0, 4) {
|
||||
0 => CustomError::CustomOne,
|
||||
1 => CustomError::CustomTwo,
|
||||
2 => CustomError::CustomThree,
|
||||
_ => CustomError::CustomFour
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl ResponseError for CustomError {
|
||||
fn error_response(&self) -> HttpResponse {
|
||||
HttpResponse::new(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/// randomly returns either () or one of the 4 CustomError variants
|
||||
//fn do_something_random() -> impl Future<Item = Result<(), FailureError>,
|
||||
// Error = ActixWebError> {
|
||||
fn do_something_random() -> impl Future<Item = (), Error = CustomError> {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
// 20% chance that () will be returned by this function
|
||||
if rng.gen_bool(2.0/10.0) {
|
||||
return fut_ok(())
|
||||
}
|
||||
|
||||
let err: CustomError = rand::random();
|
||||
return fut_err(err)
|
||||
}
|
||||
|
||||
|
||||
fn do_something(_req: HttpRequest)
|
||||
-> impl Future<Item = HttpResponse, Error = ActixWebError> {
|
||||
|
||||
do_something_random()
|
||||
.then(|result| match result {
|
||||
Ok(_) => Ok(HttpResponse::Ok()
|
||||
.body("Nothing interesting happened. Try again.")),
|
||||
|
||||
Err(err) => match err {
|
||||
CustomError::CustomOne => {
|
||||
println!("do some stuff related to CustomOne error");
|
||||
Ok(HttpResponse::Forbidden().finish())
|
||||
},
|
||||
|
||||
CustomError::CustomTwo => {
|
||||
println!("do some stuff related to CustomTwo error");
|
||||
Ok(HttpResponse::Unauthorized().finish())
|
||||
},
|
||||
|
||||
CustomError::CustomThree => {
|
||||
println!("do some stuff related to CustomThree error");
|
||||
Ok(HttpResponse::InternalServerError().finish())
|
||||
},
|
||||
|
||||
_ => {
|
||||
println!("do some stuff related to CustomFour error");
|
||||
Ok(HttpResponse::BadRequest().finish())
|
||||
}
|
||||
}
|
||||
})
|
||||
.responder()
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
::std::env::set_var("RUST_LOG", "actix_web=info");
|
||||
env_logger::init();
|
||||
let sys = actix::System::new("error_handling_example");
|
||||
|
||||
server::new(move || {
|
||||
App::new()
|
||||
.resource("/something", |r|
|
||||
r.method(Method::GET)
|
||||
.with_async(do_something))
|
||||
}).bind("127.0.0.1:8088")
|
||||
.unwrap()
|
||||
.start();
|
||||
|
||||
println!("Started http server: 127.0.0.1:8088");
|
||||
let _ = sys.run();
|
||||
}
|
Loading…
Reference in New Issue
Block a user