Tutorial
Error handling

Error handling

Return a 404 Error

With the current setup, all the routes always return a 200 Success HTTP status, no matter the response type.

In order to return a more meaningful status code to the browser, the Props struct can also be initialized with the Props::new_with_status() method.

Let's see how it works!

// src/routes/pokemons/[pokemon].rs
use serde::{Deserialize, Serialize};
-- use reqwest::Client;
++ use reqwest::{Client, StatusCode};
use tuono_lib::{Props, Request, Response};

const POKEMON_API: &str = "https://pokeapi.co/api/v2/pokemon";

#[derive(Debug, Serialize, Deserialize)]
struct Pokemon {
    name: String,
    id: u16,
    weight: u16,
    height: u16,
}

#[tuono_lib::handler]
async fn get_pokemon(req: Request, fetch: Client) -> Response {
    // The param `pokemon` is defined in the route filename [pokemon].rs
    let pokemon = req.params.get("pokemon").unwrap();

    return match fetch.get(format!("{POKEMON_API}/{pokemon}")).send().await {
        Ok(res) => {
++            if res.status() == StatusCode::NOT_FOUND {
++                return Response::Props(Props::new_with_status("{}", StatusCode::NOT_FOUND));
++             }

            let data = res.json::<Pokemon>().await.unwrap();
            Response::Props(Props::new(data))
        }
--        Err(_err) => Response::Props(Props::new(
++        Err(_err) => Response::Props(Props::new_with_status(
++            "{}",
++            StatusCode::INTERNAL_SERVER_ERROR,
        )),
    };
}

// src/routes/index.rs
use serde::{Deserialize, Serialize};
-- use reqwest::Client;
++ use reqwest::{Client, StatusCode};
use tuono_lib::{Props, Request, Response};

const ALL_POKEMON: &str = "https://pokeapi.co/api/v2/pokemon?limit=151";

#[derive(Debug, Serialize, Deserialize)]
struct Pokemons {
    results: Vec<Pokemon>,
}

#[derive(Debug, Serialize, Deserialize)]
struct Pokemon {
    name: String,
    url: String,
}

#[tuono_lib::handler]
async fn get_all_pokemons(_req: Request, fetch: Client) -> Response {
    return match fetch.get(ALL_POKEMON).send().await {
        Ok(res) => {
            let data = res.json::<Pokemons>().await.unwrap();
            Response::Props(Props::new(data))
        }
--        Err(_err) => Response::Props(Props::new(
++        Err(_err) => Response::Props(Props::new_with_status(
++            "{}", // Return empty JSON
++            StatusCode::INTERNAL_SERVER_ERROR,
        )),
    };
}

If you now try to load a not-existing Pokémon (http://localhost:3000/pokemons/tuono-pokemon) you will correctly receive a 404 status code in the console.

Edit page