Rocket - Early return from routes

Rocket web match map_err

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}}

Related Pages

Rocket - web development with Rust

Author

Gabor Szabo (szabgab)

Gabor Szabo, the author of the Rust Maven web site maintains several Open source projects in Rust and while he still feels he has tons of new things to learn about Rust he already offers training courses in Rust and still teaches Python, Perl, git, GitHub, GitLab, CI, and testing.

Gabor Szabo