Catching Panics in Requests
The CatchPanic
middleware is used to capture crashes that occur during request processing. For specific API details, please refer to the documentation.
Note: To use CatchPanic
, enable the catch-panic
feature in Cargo.toml
:
salvo = { version = "xxx", features = ["catch-panic"] }
Middleware Overview
CatchPanic
is a middleware designed to catch panics in handlers. When a panic occurs during request processing, it captures the panic and writes a 500 Internal Server Error
response instead of crashing the entire server.
Important: This middleware should be the first one in the chain to ensure it captures panics from other middlewares or handlers.
Basic Usage
use salvo_core::prelude::*;
use salvo_extra::catch_panic::CatchPanic;
#[handler]
async fn hello() {
panic!("panic error!");
}
#[tokio::main]
async fn main() {
let router = Router::new().hoop(CatchPanic::new()).get(hello);
let acceptor = TcpListener::new("0.0.0.0:5800").bind().await;
Server::new(acceptor).serve(router).await;
}
Comparison with Other Frameworks
Axum
Similar to Axum's catch_panic
middleware from Tower
:
use axum::{
Router,
routing::get,
http::StatusCode,
};
use tower::ServiceBuilder;
use tower_http::catch_panic::CatchPanicLayer;
async fn panic_handler() -> &'static str {
panic!("panic error!");
}
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/", get(panic_handler))
.layer(
ServiceBuilder::new()
.layer(CatchPanicLayer::new())
);
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
Gin (Go)
In Go's Gin framework, the equivalent is the Recovery
middleware:
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default() // Includes Recovery middleware by default
r.GET("/", func(c *gin.Context) {
panic("panic error!")
})
r.Run(":8080")
}
Example Code
import { Tab, Tabs } from 'rspress/theme';
import CatchPanicCode from '../../../../codes_md/catch-panic/src/main.mdx';
import CatchPanicCargoCode from '../../../../codes_md/catch-panic/Cargo.mdx';
<Tabs>
<Tab label="main.rs">
<CatchPanicCode/>
</Tab>
<Tab label="Cargo.toml">
<CatchPanicCargoCode/>
</Tab>
</Tabs>