Another Rocket example.
3 ways to handle error handling. I am not sure any of these would be a recommended way, but they are good for experimentation.
examples/rocket/early-return/Cargo.toml
[package]
name = "early-return"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rocket = "0.5"
rocket_dyn_templates = { version = "0.1", features = ["tera"] }
examples/rocket/early-return/src/main.rs
#[macro_use]
extern crate rocket;
use rocket_dyn_templates::{context, Template};
#[get("/")]
fn index() -> Template {
Template::render("index", context! {})
}
// deep
#[get("/deep/<number>")]
fn deep_indentation(number: &str) -> Template {
match number.parse::<i32>() {
Ok(number) => {
// lots of processing with number
Template::render("number", context! { number })
}
Err(err) => Template::render(
"message",
context! { message: format!("not a number {err}") },
),
}
}
// early return using match
#[get("/early-match/<number>")]
fn early_with_match(number: &str) -> Template {
let number = match number.parse::<i32>() {
Ok(number) => number,
Err(err) => {
return Template::render(
"message",
context! { message: format!("not a number {err}") },
)
}
};
// lots of processing with number
Template::render("number", context! { number })
}
#[get("/early-map/<number>")]
fn early_with_map_err(number: &str) -> Result<Template, Template> {
let number = number.parse::<i32>().map_err(|err| {
Template::render(
"message",
context! { message: format!("not a number {err}") },
)
})?;
// lots of processing with number
Ok(Template::render("number", context! { number }))
}
#[launch]
fn rocket() -> _ {
rocket::build()
.mount(
"/",
routes![
index,
deep_indentation,
early_with_match,
early_with_map_err
],
)
.attach(Template::fairing())
}
#[cfg(test)]
mod tests;
examples/rocket/early-return/src/tests.rs
use rocket::form::validate::Contains;
use rocket::http::Status;
use rocket::local::blocking::Client;
#[test]
fn main() {
let client = Client::tracked(super::rocket()).unwrap();
let response = client.get("/").dispatch();
assert_eq!(response.status(), Status::Ok);
assert_eq!(
response.headers().get_one("Content-Type").unwrap(),
"text/html; charset=utf-8"
);
assert!(response
.into_string()
.unwrap()
.contains(r#"<a href="/deep/42">number</a> or <a href="/deep/hello">string</a>"#));
for path in ["deep", "early-match", "early-map"] {
let response = client.get(format!("/{path}/42")).dispatch();
assert_eq!(response.status(), Status::Ok);
assert_eq!(
response.headers().get_one("Content-Type").unwrap(),
"text/html; charset=utf-8"
);
assert_eq!(response.into_string(), Some("Number: 42".to_string()));
let response = client.get(format!("/{path}/hello")).dispatch();
assert_eq!(response.status(), Status::Ok);
assert_eq!(
response.headers().get_one("Content-Type").unwrap(),
"text/html; charset=utf-8"
);
assert_eq!(
response.into_string(),
Some("Message: not a number invalid digit found in string".to_string())
);
}
}
examples/rocket/early-return/templates/index.html.tera
Try
Deep: <a href="/deep/42">number</a> or <a href="/deep/hello">string</a><br>
Early return with match: <a href="/early-match/42">number</a> or <a href="/early-match/hello">string</a><br>
Early return map_err: <a href="/early-map/42">number</a> or <a href="/early-map/hello">string</a><br>
examples/rocket/early-return/templates/message.html.tera
Message: {{message}}
examples/rocket/early-return/templates/number.html.tera
Number: {{number}}