use crate::{traits::MiddlewareTrait, Middleware};
use axum::{http::StatusCode, response::IntoResponse};
use tower_http::catch_panic::CatchPanicLayer;
pub struct CatchPanic;
impl MiddlewareTrait for CatchPanic {
fn handle() -> Middleware {
Box::new(|router| Ok(router.layer(CatchPanicLayer::custom(handle_panic))))
}
}
fn handle_panic(error: Box<dyn std::any::Any + Send + 'static>) -> axum::response::Response {
let message = if let Some(s) = error.downcast_ref::<String>() {
std::borrow::Cow::Owned(s.to_owned())
} else if let Some(s) = error.downcast_ref::<&str>() {
std::borrow::Cow::Borrowed(*s)
} else {
std::borrow::Cow::Borrowed("Unknown panic message")
};
tracing::error!(error = ?message, "panic");
#[cfg(not(feature = "response-json"))]
{
(StatusCode::INTERNAL_SERVER_ERROR, message).into_response()
}
#[cfg(feature = "response-json")]
{
crate::response::json()
.code(StatusCode::INTERNAL_SERVER_ERROR)
.message(message)
.into_response()
}
}