简体   繁体   English

在自定义结构上实现 actix_web::Responder 特性

[英]Implement actix_web::Responder trait on a custom structure

I'm using actix-web v4.我正在使用 actix-web v4。

I'm trying to implement a web service with a custom structure for handling errors:我正在尝试使用用于处理错误的自定义结构来实现 web 服务:

pub struct ApiError {
    pub message: String,
    pub code: ErrorEnum,
    pub details: Vec<ErrorDetail>,
}

This is an example of function that returns this structure on a failure:这是 function 的示例,它在失败时返回此结构:

pub fn my_func_that_fails() -> Result<(), ApiError> {
    Err(ApiError::default())
}

I have this function to map ApiError s to HttpResponse s:我有这个 function 到 map ApiError s 到HttpResponse s:

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),
        //...
    }
}

This is how I use it in a handler:这就是我在处理程序中使用它的方式:

pub async fn my_handler(req: actix_web::HttpRequest) -> impl actix_web::Responder {
    if let Err(e) = my_func_that_fails() {
        return err_to_http(&e);
    }
}

I would like to be able to use it this way:我希望能够以这种方式使用它:

pub async fn my_handler(req: actix_web::HttpRequest) -> impl actix_web::Responder {
    my_func_that_fails()?;
}

For this I need to implement the trait actix_web::Responder , but I can't find documentation online to do that.为此,我需要实现特征actix_web::Responder ,但我无法在网上找到文档来执行此操作。 This is my attempt at doing it, but I don't know what to put in the Body type, nor if I'm doing it correctly:这是我尝试这样做的尝试,但我不知道在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()
    }
}

The following should work:以下应该工作:

impl actix_web::Responder for ApiError {
    type Body = actix_web::body::BoxBody;

    fn respond_to(self, req: &actix_web::HttpRequest) -> actix_web::HttpResponse<Self::Body> {
        err_to_http(&self.api_error)
    }
}

Although, this technically isn't accurate because implementing Responder for ApiError will not solve your problem.虽然,这在技术上并不准确,因为为 ApiError 实施Responder不会解决您的问题。 I recommend something like this instead:我推荐这样的东西:

pub async fn my_handler(req: actix_web::HttpRequest) -> Result<actix_web::HttpResponse, ApiError> {
    my_func_that_fails()?;
}

and then have ApiError implement the ResponseError trait, like so:然后让ApiError实现ResponseError特性,如下所示:

impl actix_web::error::ResponseError for ApiError {
    fn error_response(&self) -> actix_web::HttpResponse {
        match error.code {
            ErrorEnum::NotFound => actix_web::HttpResponse::NotFound()
                .content_type("application/json; charset=utf-8")
                .json(error),
            //...
        }
    }

    fn status_code(&self) -> actix_web::http::StatusCode {
        // get status code here
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM