1
0
mirror of https://github.com/actix/examples synced 2025-02-02 17:39:05 +01:00

104 lines
3.0 KiB
Rust
Raw Normal View History

2018-08-07 12:03:16 -04:00
/*
2019-03-09 18:03:09 -08:00
The goal of this example is to show how to propagate a custom error type,
to a web handler that will evaluate the type of error that
2018-08-07 12:03:16 -04:00
was raised and return an appropriate HTTPResponse.
This example uses a 50/50 chance of returning 200 Ok, otherwise one of four possible
2019-03-09 18:03:09 -08:00
http errors will be chosen, each with an equal chance of being selected:
2018-08-07 12:03:16 -04:00
1. 403 Forbidden
2. 401 Unauthorized
3. 500 InternalServerError
4. 400 BadRequest
*/
2019-03-09 18:03:09 -08:00
use actix_web::{web, App, Error, HttpResponse, HttpServer, ResponseError};
use derive_more::Display; // naming it clearly for illustration purposes
use rand::{
distributions::{Distribution, Standard},
thread_rng, Rng,
2018-08-07 12:03:16 -04:00
};
2019-03-09 18:03:09 -08:00
#[derive(Debug, Display)]
2018-08-07 12:03:16 -04:00
pub enum CustomError {
2019-03-09 18:03:09 -08:00
#[display(fmt = "Custom Error 1")]
2018-08-07 12:03:16 -04:00
CustomOne,
2019-03-09 18:03:09 -08:00
#[display(fmt = "Custom Error 2")]
2018-08-07 12:03:16 -04:00
CustomTwo,
2019-03-09 18:03:09 -08:00
#[display(fmt = "Custom Error 3")]
2018-08-07 12:03:16 -04:00
CustomThree,
2019-03-09 18:03:09 -08:00
#[display(fmt = "Custom Error 4")]
CustomFour,
2018-08-07 12:03:16 -04:00
}
impl Distribution<CustomError> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> CustomError {
match rng.gen_range(0..4) {
2018-08-07 12:03:16 -04:00
0 => CustomError::CustomOne,
1 => CustomError::CustomTwo,
2 => CustomError::CustomThree,
2019-03-09 18:03:09 -08:00
_ => CustomError::CustomFour,
2018-08-07 12:03:16 -04:00
}
}
}
2022-02-06 08:25:38 +00:00
/// Actix Web uses `ResponseError` for conversion of errors to a response
2018-08-07 12:03:16 -04:00
impl ResponseError for CustomError {
fn error_response(&self) -> HttpResponse {
2019-03-09 18:03:09 -08:00
match self {
CustomError::CustomOne => {
println!("do some stuff related to CustomOne error");
HttpResponse::Forbidden().finish()
}
CustomError::CustomTwo => {
println!("do some stuff related to CustomTwo error");
HttpResponse::Unauthorized().finish()
}
CustomError::CustomThree => {
println!("do some stuff related to CustomThree error");
HttpResponse::InternalServerError().finish()
}
_ => {
println!("do some stuff related to CustomFour error");
HttpResponse::BadRequest().finish()
}
}
2018-08-07 12:03:16 -04:00
}
}
/// randomly returns either () or one of the 4 CustomError variants
2019-12-07 23:59:24 +06:00
async fn do_something_random() -> Result<(), CustomError> {
2018-08-07 12:03:16 -04:00
let mut rng = thread_rng();
// 20% chance that () will be returned by this function
2019-03-09 18:03:09 -08:00
if rng.gen_bool(2.0 / 10.0) {
2019-12-07 23:59:24 +06:00
Ok(())
2019-03-09 18:03:09 -08:00
} else {
2019-12-07 23:59:24 +06:00
Err(rand::random::<CustomError>())
2018-08-07 12:03:16 -04:00
}
}
2019-12-07 23:59:24 +06:00
async fn do_something() -> Result<HttpResponse, Error> {
do_something_random().await?;
Ok(HttpResponse::Ok().body("Nothing interesting happened. Try again."))
2018-08-07 12:03:16 -04:00
}
2020-09-12 16:49:45 +01:00
#[actix_web::main]
2019-12-07 23:59:24 +06:00
async fn main() -> std::io::Result<()> {
2022-03-06 00:41:32 +00:00
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
log::info!("starting HTTP server at http://localhost:8080");
2018-08-07 12:03:16 -04:00
2019-03-09 18:03:09 -08:00
HttpServer::new(move || {
2022-02-18 02:44:02 +00:00
App::new().service(web::resource("/something").route(web::get().to(do_something)))
2019-03-09 18:03:09 -08:00
})
2022-03-06 00:41:32 +00:00
.bind(("127.0.0.1", 8080))?
2019-12-25 20:48:33 +04:00
.run()
2019-12-07 23:59:24 +06:00
.await
2018-08-07 12:03:16 -04:00
}