Rocket 的错误处理,最好分两层理解:
#1. 框架层拦截失败
例如:
- 路由不匹配
- guard 失败
- 参数解析失败
- JSON / 表单载荷不合法
这些像什么?
像:
火箭还没进入真正点火阶段,就已经在检查清单环节被拦下。
#2. 业务层执行失败
例如:
- 数据库里找不到任务
- 当前状态不允许再次发射
- 配额不足
- 外部系统失败
这类通常用 Result<T, E> 来表达。
一个典型写法:
use rocket::http::Status;
use rocket::response::status;
use rocket::serde::json::Json;
#[derive(serde::Serialize)]
#[serde(crate = "rocket::serde")]
struct ErrorMessage {
error: String,
}
#[derive(serde::Serialize)]
#[serde(crate = "rocket::serde")]
struct Mission {
id: u64,
name: String,
}
#[get("/missions/<id>")]
fn get_mission(id: u64) -> Result<Json<Mission>, status::Custom<Json<ErrorMessage>>> {
if id == 404 {
return Err(status::Custom(
Status::NotFound,
Json(ErrorMessage {
error: "mission not found".into(),
}),
));
}
Ok(Json(Mission {
id,
name: "orbital-check".into(),
}))
}这里的心智是:
不是控制塔炸了,而是控制塔发出一份标准化中止报告。
Rocket 的优雅点在于:
- 成功路径写得很清楚
- 失败路径也能保持统一响应风格