在Rust 基礎(chǔ)教程中,我們學(xué)習(xí)到rust的基本錯(cuò)誤處理方式,可以用
?語(yǔ)法糖來方便快捷地向上拋出錯(cuò)誤,。 本章將和大家一起學(xué)習(xí)封裝統(tǒng)一的錯(cuò)誤響應(yīng),并使用thiserror庫(kù)統(tǒng)一轉(zhuǎn)換第三方包的錯(cuò)誤類型為我們自定義的錯(cuò)誤類型;
導(dǎo)入依賴
# Cargo.toml
...
[dependencies.thiserror]
version = "1.0.63"
...
創(chuàng)建自定義錯(cuò)誤類型
// error.rs 為方便管理,我們單獨(dú)創(chuàng)建一個(gè)文件(模塊) 管理錯(cuò)誤類型相關(guān)代碼
use thiserror::Error;
#[derive(Debug,Error)]
pub enum MyError{
// error注解是thiserror 庫(kù) 提供的宏函數(shù),里面可以添加錯(cuò)誤信息
#[error("default error")]
Default,
// 利用enum的特性,錯(cuò)誤類型里面可以接受元組,并在文本信息里填充
#[error("error info:{1}")]
WithCodeMsg(i32,String),
}
因?yàn)槲覀兊哪繕?biāo)是將MyError 作為統(tǒng)一錯(cuò)誤類型,而在代碼中我們需要使用第三方庫(kù),這些庫(kù)拋出的錯(cuò)誤可能并非標(biāo)準(zhǔn)庫(kù)的錯(cuò)誤,而是像MyError一樣的自定義錯(cuò)誤,因此我們需要通過實(shí)現(xiàn) From 將MyError 和第三方庫(kù)里的錯(cuò)誤具備相互轉(zhuǎn)化的能力
thiserror 提供了快速實(shí)現(xiàn)From 的方法
use thiserror::Error;
#[derive(Debug,Error)]
pub enum MyError{
#[error("db error {0}")]
DatabaseError(#[from] sea_orm::DbErr)
}
將錯(cuò)誤通過接口返回
在axum 中,需要為返回內(nèi)容 實(shí)現(xiàn) IntoResponse ,這樣axum才會(huì)正確識(shí)別hanlder的響應(yīng)
use axum::Json
use thiserror::Error;
#[derive(Debug, Error)]
pub enum MyError {
#[error("error info:{1}")]
WithCodeMsg(i32, String),
#[error("default error")]
Default,
#[error("dberror:{0}")]
DbError(#[from] sea_orm::DbErr),
}
// 新建結(jié)構(gòu)體可作為json對(duì)象返回
#[derive(Debug,Serialize)]
struct ErrResp {
code:i32,
msg:String,
}
impl axum::response::IntoResponse for MyError {
fn into_response(self) -> Response {
let code = match self {
// 自定義返回的code和msg
MyError::WithCodeMsg(c,ref _m ) => {
c
},
// 自定義code 和默認(rèn)msg
MyError::DbError(_) => -2,
// 默認(rèn)code和msg
_ => -1,
};
// 轉(zhuǎn)換錯(cuò)誤信息為String
let msg = self.to_string();
// 返回json
Json(ErrResp { code, msg }).into_response()
}
}
示例
...
// 編寫handler
pub async fn get_error()->MyError{
MyError::WithCodeMsg(-1,"error".to_string())
}
...
直接請(qǐng)求后獲得錯(cuò)誤響應(yīng):
{
"code": -1,
"msg": "error info:error"
}