[英]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
是一种用法特征,就像IntoIterator
: Vec
和HashMap
都实现了它,但这并不意味着您可以将任意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.注意:像thiserror
或snafu
这样的库提供了工具来更容易地创建定制的错误类型,以及从现有错误类型的转换。
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.