简体   繁体   English

为什么这些错误不会自动转换为我的自定义错误,即使它们同时实现了 std::error::Error 特征?

[英]Why these errors are not automagically converted to my custom error even if they are implementing both std::error::Error trait?

Reproduction project (single main.rs file): https://github.com/frederikhors/iss-custom-err .复制项目(单个 main.rs 文件): https://github.com/frederikhors/iss-custom-err

I'm trying to create a custom error for my app:我正在尝试为我的应用创建自定义错误:

pub struct AppError {
    message: String,
    error: anyhow::Error, // In the future I would also avoid anyhow
}

I'm trying to use it in my code but as you can see I'm getting the below compiler errors, why?我正在尝试在我的代码中使用它,但如您所见,我遇到了以下编译器错误,为什么?

Isn't my AppError implementing the trait std::error::Error correctly?我的AppError不是正确地实现了特征std::error::Error吗?

I would expect an auto conversion from hyper error to AppError being both error:Error traits, am I wrong?我希望从hyper error 到AppError的自动转换都是 error:Error 特征,我错了吗?

error[E0277]: `?` couldn't convert the error to `AppError`
  --> src\main.rs:20:44
   |
20 |                     .body(Body::from(body))?;
   |                                            ^ the trait `From<hyper::http::Error>` is not implemented for `AppError`
   |
   = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
   = help: the following other types implement trait `FromResidual<R>`:
             <Result<T, F> as FromResidual<Result<Infallible, E>>>
             <Result<T, F> as FromResidual<Yeet<E>>>
   = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, hyper::http::Error>>` for `Result<(), AppError>`

error[E0277]: `?` couldn't convert the error to `AppError`
  --> src\main.rs:24:19
   |
24 |             .await?;
   |                   ^ the trait `From<hyper::Error>` is not implemented for `AppError`
   |
   = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
   = help: the following other types implement trait `FromResidual<R>`:
             <Result<T, F> as FromResidual<Result<Infallible, E>>>
             <Result<T, F> as FromResidual<Yeet<E>>>
   = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, hyper::Error>>` for `Result<(), AppError>`

For more information about this error, try `rustc --explain E0277`.

I would expect an auto conversion from hyper error to AppError being both error:Error traits, am I wrong?我希望从 hyper error 到 AppError 的自动转换都是 error:Error 特征,我错了吗?

Yes.是的。 Error is a usage trait, it's like IntoIterator : both Vec and HashMap implement it, but that doesn't mean you can convert an arbitrary Vec to a HashMap . Error是一种用法特征,就像IntoIteratorVecHashMap都实现了它,但这并不意味着您可以将任意Vec转换为HashMap

Let alone that Rust will do it for you: Rust generally favors intentionality, it avoids large multi-use concepts.更不用说 Rust 会为你做这件事了:Rust 通常倾向于意向性,它避免了大的多用途概念。 So all error tells you is that you can display the type, and may be able to get its source .所以所有的error都告诉你,你可以显示类型,并且可以得到它的source It says nothing about conversion, except for conversion to a Box<dyn Error> (because Error is object-safe).除了转换为Box<dyn Error> (因为Error是对象安全的)之外,它没有提及转换。

So as the compiler error tells you , if you want Rust (and specifically ? ) to perform the conversion, you need to implement the From trait .因此,正如编译器错误告诉您的那样,如果您希望 Rust(特别是? )执行转换,则需要实现From特征

Note: libraries like thiserror or snafu provide tooling to more easily create bespoke error types, and conversions from existing error types.注意:像thiserrorsnafu这样的库提供了工具来更容易地创建定制的错误类型,以及从现有错误类型的转换。

On discord a kind user helped me understand. discord上有好心的用户帮我理解了。

What I need is a generic impl :我需要的是一个通用的impl

impl<T: error::Error + Send + Sync + 'static> From<T> for AppError {
    fn from(e: T) -> Self {
        Self { message: e.to_string(), error: anyhow::Error::new(e) }
    }
}

That's it!就是这样!

暂无
暂无

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

相关问题 实现Read trait:trait绑定`std :: error :: Error +&#39;static:std :: marker :: Sized`不满足 - Implementing Read trait : trait bound `std::error::Error + 'static: std::marker::Sized` is not satisfied 为什么 rustc compile 抱怨我的简单代码“特征 std::io::Read 没有为 Result 实现<File, anyhow::Error> ” - why rustc compile complain my simple code “the trait std::io::Read is not implemented for Result<File, anyhow::Error>” 为什么即使T实现了特征,也出现错误“未对&mut T实现特征Foo”? - Why do I get the error “the trait `Foo` is not implemented for `&mut T`” even though T implements the trait? 实现Index trait时无约束的生命周期错误 - Unconstrained lifetime error when implementing Index trait 实现自定义错误枚举时,特征绑定 io::Error: Clone is not 日本 - The trait bound io::Error: Clone is not satisfied when implementing a custom error enum 为什么不能将 std::num::ParseIntError 转换为 Box<dyn std::error::error> ?</dyn> - Why can't a std::num::ParseIntError be converted into Box<dyn std::error::Error>? Rustlings Errors3.rs 从字符串错误转换 - 未为 `std::string::String` 实现特征 - Rustlings Errors3.rs Convert From String Error - Trait Not Implemented for `std::string::String` 从实现`Error`特征的对象实现泛型转换 - Implementing a generic conversion from an object implementing the `Error` trait 没有为 Result 实现 trait `Future`<std::net::tcplistener, std::io::error></std::net::tcplistener,> - the trait `Future` is not implemented for `Result<std::net::TcpListener, std::io::Error> 为什么 Rust “From”特征实现会给出生命周期错误,而自定义特征却不会? - Why does Rust "From" trait implementation give lifetime error, but custom trait does not?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM