【问题标题】:How to convert tera::Error to actix_web::Error?如何将 tera::Error 转换为 actix_web::Error?
【发布时间】:2021-09-19 06:11:12
【问题描述】:

我正在研究rust/actix/tera,但无法弄清楚如何在tera::Error 上实现ResponseError trait,或者如何将tera::Error 转换为actix_web::Error

用下面的代码sn-p:

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> {}

我做错了什么?

【问题讨论】:

  • 错误:只有当前 crate 中定义的特征可以用于任意类型这意味着你不能,你可能想改变你的问题,如如何转换 @987654336 @到actix_web::Error,或者联合他们。

标签: rust actix-web rust-actix tera


【解决方案1】:

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

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

编译器抛出一个错误,说如果只实现 tera 错误ResponseError,它就可以进行转换。但是你不能让它实现那个 trait,因为“trait orphan rule”,它说你不能从你自己的 crate 外部实现一个 trait 到你自己的 crate 外部的一个类型上。

您可以将tera::Error 包装在您自己的结构中,然后为此实现ResponseError,如outlined in this question

但是有一个更简单的解决方案:actix-web 提供了一个whole swathe of helper functions 用于转换错误,你可以像这样使用它:

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

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

另请参阅 actix-web documentation for error handling

Caveat Emptor:此解决方案未经测试,我从未使用过 teraactix-web,而是从浏览他们的文档中收集到这一点。

【讨论】:

  • 非常感谢您的努力!如果您通过将匹配 Err arm 更改为 Err(e) =&gt; Err(error::ErrorInternalServerError(e)) 来更新您的答案,我很乐意接受。
  • @NarūnasK 已经完成,但请注意,如果您在文件中 use error::ErrorInternalServerError;,它仍然有效
猜你喜欢
  • 2020-04-23
  • 2020-03-28
  • 2020-03-26
  • 2018-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多