在actix-web v4中为自定义ApiError结构体实现Responder trait
问题
我正在使用actix-web v4,尝试实现一个采用自定义结构体处理错误的Web服务,定义的错误结构体如下:
pub struct ApiError { pub message: String, pub code: ErrorEnum, pub details: Vec<ErrorDetail>, }
已有一个返回该错误结构体的示例函数:
pub fn my_func_that_fails() -> Result<(), ApiError> { Err(ApiError::default()) }
同时编写了将ApiError转换为HttpResponse的函数:
pub fn err_to_http(error: &ApiError) -> actix_web::HttpResponse { match error.code { ErrorEnum::NotFound => actix_web::HttpResponse::NotFound() .content_type("application/json; charset=utf-8") .json(error), //... } }
当前在处理器中需要通过判断错误并调用转换函数返回响应,但希望简化成以下方式:
pub async fn my_handler(req: actix_web::HttpRequest) -> impl actix_web::Responder { my_func_that_fails()?; }
这需要为ApiError实现actix_web::Responder trait,但不清楚如何设置Body类型以及正确实现,我的尝试如下:
impl actix_web::Responder for ApiError { type Body = ???; fn respond_to(self, req: &actix_web::HttpRequest) -> actix_web::HttpResponse<Self::Body> { err_to_http(&self.api_error).into_future() } }
请求指导正确的实现方式。
解决方案
要让ApiError实现Responder trait,只需匹配err_to_http返回的HttpResponse的Body类型即可,具体实现如下:
正确代码示例
use actix_web::{body::BoxBody, HttpResponse, Responder}; impl Responder for ApiError { type Body = BoxBody; fn respond_to(self, _req: &actix_web::HttpRequest) -> HttpResponse<Self::Body> { err_to_http(&self) } }
关键说明
- 由于
err_to_http中使用.json()序列化错误,该方法返回的HttpResponse默认采用BoxBody作为Body类型,因此直接将关联类型Body指定为BoxBody即可 respond_to方法无需额外转换逻辑,直接调用err_to_http(&self)就能返回符合要求的HttpResponse<BoxBody>- 实现完成后,处理器中即可通过
?直接返回ApiError,actix-web会自动调用respond_to将其转换为标准HTTP响应
内容的提问来源于stack exchange,提问作者Xobtah
相关产品推荐
相关产品推荐

