use crate::constant::ResCode;
use crate::error::CoolError;
use salvo::prelude::*;
use serde::Serialize;
use tracing::error;
#[derive(Debug, Serialize)]
pub struct ErrorResponse {
pub code: i32,
pub message: String,
}
pub struct ExceptionFilter;
#[async_trait::async_trait]
impl Handler for ExceptionFilter {
async fn handle(
&self,
req: &mut Request,
depot: &mut Depot,
res: &mut Response,
ctrl: &mut FlowCtrl,
) {
ctrl.call_next(req, depot, res).await;
let status = res.status_code.unwrap_or(StatusCode::OK);
if status.is_client_error() || status.is_server_error() {
if res.body.is_none() {
if let Ok(err_msg) = depot.get::<String>("error") {
error!("Request error: {}", err_msg);
let error_response = ErrorResponse {
code: status.as_u16() as i32,
message: err_msg.clone(),
};
res.render(Json(error_response));
} else {
let error_response = ErrorResponse {
code: ResCode::CommError.code(),
message: "请求处理失败".to_string(),
};
res.render(Json(error_response));
}
}
}
}
}
pub fn exception_filter() -> ExceptionFilter {
ExceptionFilter
}
pub fn handle_error(err: &CoolError) -> ErrorResponse {
error!("CoolError: {:?}", err);
ErrorResponse {
code: err.code().code(),
message: err.to_string(),
}
}