如何将 tera::Error 转换为 actix_web::Error?

2024-05-18

我正在学习rust/actix/tera并且不知道如何实施ResponseError上的特质tera::Error,或者如何转换tera::Error to actix_web::Error.

使用以下代码片段:

match TEMPLATES.render("index.html", &ctx) {
    Ok(s) => Ok(HttpResponse::Ok().body(s)),
    Err(e) => Err(e),
}

我收到错误:

mismatched types

expected struct `actix_web::Error`, found struct `tera::Error`rustc(E0308)
main.rs(71, 23): expected struct `actix_web::Error`, found struct `tera::Error`

所以我尝试了以下方法:

match TEMPLATES.render("index.html", &ctx) {
    Ok(s) => Ok(HttpResponse::Ok().body(s)),
    Err(e) => Err(e.into()),
}

但在这种情况下我得到:

the trait bound `tera::Error: actix_web::ResponseError` is not satisfied

the trait `actix_web::ResponseError` is not implemented for `tera::Error`

note: required because of the requirements on the impl of `std::convert::From<tera::Error>` for `actix_web::Error`
note: required because of the requirements on the impl of `std::convert::Into<actix_web::Error>` for `tera::Error`rustc(E0277)
main.rs(71, 25): the trait `actix_web::ResponseError` is not implemented for `tera::Error`

所以最后我尝试过:

use actix_web::{get, post, web, error, Error, ResponseError,
    HttpRequest, HttpResponse, HttpServer,
    App, Responder};
use tera::{Tera, Context};
use tera;

impl ResponseError for tera::Error {}

但现在得到:

only traits defined in the current crate can be implemented for arbitrary types

impl doesn't use only types from inside the current crate

note: define and implement a trait or new type insteadrustc(E0117)
main.rs(12, 1): impl doesn't use only types from inside the current crate
main.rs(12, 24): `tera::Error` is not defined in the current crate

我有的函数签名match块如下:

#[get("/")]
async fn tst() -> Result<HttpResponse, Error> {}

我究竟做错了什么?


正如您已经发现的那样,into()不能用于转换tera::Error to an actix_web::Error因为没有直接定义这样的转换。在这种情况下,它会给您一个稍微误导性的错误 - 因为存在此转换:

impl<T> From<T> for Error
where
    T: 'static + ResponseError, 

编译器抛出一个错误,表示如果仅实现了 tera 错误ResponseError,它可以进行转换。但是你不能让它实现这个特征,因为“特征孤儿规则”,它说你不能将你自己的板条箱之外的特征实现到你自己的板条箱之外的类型上。

你可以把tera::Error在你自己的结构中,然后实现ResponseError为此,作为在这个问题中概述 https://stackoverflow.com/questions/25413201/how-do-i-implement-a-trait-i-dont-own-for-a-type-i-dont-own.

但有一个更简单的解决方案:actix-web 提供了一个整个辅助函数 https://docs.rs/actix-web/3.3.2/actix_web/error/index.html#functions用于转换错误,您可以像这样使用:

match TEMPLATES.render("index.html", &ctx) {
    Ok(s) => Ok(HttpResponse::Ok().body(s)),
    Err(e) => Err(error::ErrorInternalServerError(e)),
}

提供的帮助程序将提供的错误映射到指定的 HTTP 响应代码中,因此您可以选择最能代表发生的错误的一个。

另请参阅 actix-web错误处理的文档 https://actix.rs/docs/errors/.

买者自负:这个解决方案未经测试,我从未使用过tera nor actix-web,而是我通过浏览他们的文档收集到的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 tera::Error 转换为 actix_web::Error? 的相关文章

随机推荐