Catcher

Quando uma Response retorna um código de status de erro e o Body dentro da página está vazio, o Salvo tentará capturar esse erro usando um Catcher e exibir uma página de erro amigável ao usuário.

Você pode obter um Catcher padrão do sistema chamando Catcher::default(), e então adicioná-lo ao Service.

use salvo::catcher::Catcher;

Service::new(router).catcher(Catcher::default());

O Catcher padrão suporta o envio de páginas de erro nos formatos XML, JSON, HTML e Text.

Você pode adicionar manipuladores personalizados de captura de erro ao Catcher anexando hoops a este Catcher padrão. Esses manipuladores de captura de erro ainda são do tipo Handler.

Você pode adicionar vários manipuladores personalizados de captura de erro ao Catcher através de hoops. Os manipuladores de erro personalizados podem chamar o método FlowCtrl::skip_next após processar um erro para pular os manipuladores de erro subsequentes e retornar antecipadamente.

main.rs
Cargo.toml
use salvo::catcher::Catcher;
use salvo::prelude::*;

// Handler that returns a simple "Hello World" response
#[handler]
async fn hello() -> &'static str {
    "Hello World"
}

// Handler that deliberately returns a 500 Internal Server Error
#[handler]
async fn error500(res: &mut Response) {
    res.status_code(StatusCode::INTERNAL_SERVER_ERROR);
}

#[tokio::main]
async fn main() {
    // Initialize logging system
    tracing_subscriber::fmt().init();

    // Create and start server with custom error handling
    let acceptor = TcpListener::new("0.0.0.0:8698").bind().await;
    Server::new(acceptor).serve(create_service()).await;
}

// Create service with custom error handling
fn create_service() -> Service {
    // Set up router with two endpoints:
    // - / : Returns "Hello World"
    // - /500 : Triggers a 500 error
    let router = Router::new()
        .get(hello)
        .push(Router::with_path("500").get(error500));

    // Add custom error catcher for 404 Not Found errors
    Service::new(router).catcher(Catcher::default().hoop(handle404))
}

// Custom handler for 404 Not Found errors
#[handler]
async fn handle404(&self, _req: &Request, _depot: &Depot, res: &mut Response, ctrl: &mut FlowCtrl) {
    // Check if the error is a 404 Not Found
    if StatusCode::NOT_FOUND == res.status_code.unwrap_or(StatusCode::NOT_FOUND) {
        // Return custom error page
        res.render("Custom 404 Error Page");
        // Skip remaining error handlers
        ctrl.skip_rest();
    }
}