If the status code of Response returned by the request is an error, and the Body in the page is empty, then salvo will try to use Catcher to catch the error and display a friendly error page.

A simple way to create a custom Catcher is to return a system default Catcher via Catcher::default(), and then add it to Service.

use salvo::catcher::Catcher;


The default Catcher supports sending error pages in XML, JSON, HTML, Text formats.

You can add a custom error catcher to Catcher by adding hoop to the default Catcher. The error catcher is still Handler.

use salvo::catcher::Catcher;
use salvo::prelude::*;

async fn hello() -> &'static str {
    "Hello World"
async fn error500(res: &mut Response) {

async fn main() {

    let acceptor = TcpListener::new("").bind().await;

fn create_service() -> Service {
    let router = Router::new()

async fn handle404(&self, _req: &Request, _depot: &Depot, res: &mut Response, ctrl: &mut FlowCtrl) {
    if let Some(StatusCode::NOT_FOUND) = res.status_code {
        res.render("Custom 404 Error Page");
name = "example-custom-error-page"
version = "0.1.0"
edition = "2021"
publish = false

salvo.workspace = true
tokio = { version = "1", features = ["macros"] }
tracing = "0.1"
tracing-subscriber = "0.3"