fix(api): 优化 /health 端点错误提示

This commit is contained in:
2026-04-19 00:38:13 +08:00
parent 988828b984
commit 52991dcfd5

View File

@@ -1,21 +1,62 @@
use actix_web::{web, get, HttpResponse, Responder};
use sqlx::postgres::PgPool;
use serde::Serialize;
#[derive(Serialize)]
pub struct HealthResponse {
pub status: String,
pub database: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hint: Option<String>,
}
#[get("/health")]
pub async fn health_check(pool: web::Data<PgPool>) -> impl Responder {
// 检查数据库连接
match sqlx::query("SELECT 1").fetch_one(pool.get_ref()).await {
Ok(_) => HttpResponse::Ok().json(serde_json::json!({
"status": "healthy",
"database": "connected"
})),
Ok(_) => {
HttpResponse::Ok().json(HealthResponse {
status: "ok".to_string(),
database: "connected".to_string(),
error: None,
hint: None,
})
}
Err(e) => {
tracing::error!("健康检查失败: {}", e);
HttpResponse::ServiceUnavailable().json(serde_json::json!({
"status": "unhealthy",
"database": "disconnected",
"error": "数据库连接失败"
}))
let err_str = e.to_string();
let (error_msg, hint_msg) = if err_str.contains("connection refused") {
(
"无法连接到数据库".to_string(),
"请检查数据库服务是否运行".to_string(),
)
} else if err_str.contains("Connection timed out") {
(
"数据库连接超时".to_string(),
"请检查网络连接".to_string(),
)
} else if err_str.contains("does not exist") {
("数据库不存在".to_string(), "请检查数据库配置".to_string())
} else if err_str.contains("28P01") {
(
"数据库认证失败".to_string(),
"用户名或密码错误".to_string(),
)
} else {
(
"数据库连接失败".to_string(),
"请查看服务器日志获取详细信息".to_string(),
)
};
tracing::error!("健康检查失败: {:?}", e);
HttpResponse::ServiceUnavailable().json(HealthResponse {
status: "error".to_string(),
database: "disconnected".to_string(),
error: Some(error_msg),
hint: Some(hint_msg),
})
}
}
}