[英]How to make error-chain errors compatible with Failure errors?
Given the following code: 给出以下代码:
extern crate dotenv; // v0.11.0
#[macro_use]
extern crate failure; // v0.1.1
#[derive(Debug, Fail)]
#[fail(display = "oh no")]
pub struct Error(dotenv::Error);
Due to the fact that error-chain
(v0.11, the latest) does not guarantee that its wrapped error is Sync
( open PR to fix the issue ) I get an error saying that Sync
is not implemented for dotenv::Error
: 由于
error-chain
(v0.11,最新版本)不能保证其包装错误是Sync
( 打开PR以解决问题 ),我收到一条错误消息,说明没有为dotenv::Error
实现Sync
:
error[E0277]: the trait bound `std::error::Error + std::marker::Send + 'static: std::marker::Sync` is not satisfied
--> src/main.rs:5:17
|
5 | #[derive(Debug, Fail)]
| ^^^^ `std::error::Error + std::marker::Send + 'static` cannot be shared between threads safely
|
= help: the trait `std::marker::Sync` is not implemented for `std::error::Error + std::marker::Send + 'static`
= note: required because of the requirements on the impl of `std::marker::Sync` for `std::ptr::Unique<std::error::Error + std::marker::Send + 'static>`
= note: required because it appears within the type `std::boxed::Box<std::error::Error + std::marker::Send + 'static>`
= note: required because it appears within the type `std::option::Option<std::boxed::Box<std::error::Error + std::marker::Send + 'static>>`
= note: required because it appears within the type `error_chain::State`
= note: required because it appears within the type `dotenv::Error`
= note: required because it appears within the type `Error`
What's the minimal amount of boilerplate/work I can get away with to make these types play nicely together? 什么是最小量的样板/工作,我可以让这些类型很好地一起玩? The shortest thing I've been able to come up with is adding an
ErrorWrapper
newtype so that I can implement Error
on an Arc<Mutex<ERROR_CHAIN_TYPE>>
: 我能想到的最简单的事情就是添加一个
ErrorWrapper
newtype,这样我就可以在Arc<Mutex<ERROR_CHAIN_TYPE>>
上实现Error
:
use std::fmt::{self, Debug, Display, Formatter};
use std::sync::{Arc, Mutex};
#[derive(Debug, Fail)]
#[fail(display = "oh no")]
pub struct Error(ErrorWrapper<dotenv::Error>);
#[derive(Debug)]
struct ErrorWrapper<T>(Arc<Mutex<T>>)
where
T: Debug;
impl<T> Display for ErrorWrapper<T>
where
T: Debug,
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "oh no!")
}
}
impl<T> ::std::error::Error for ErrorWrapper<T>
where
T: Debug,
{
fn description(&self) -> &str {
"whoops"
}
}
// ... plus a bit more for each `From<T>` that needs to be converted into
// `ErrorWrapper`
Is this the right way to go about it? 这是正确的方法吗? Is there something that will have less code/runtime cost for converting into an
Arc<Mutex<T>>
for things that don't need it? 对于那些不需要它的东西,是否会有更少的代码/运行时成本转换为
Arc<Mutex<T>>
?
The only thing that I can suggest is to remove the Arc
type. 我唯一可以建议删除
Arc
类型。
If you have something that is not Sync
then wrap into a Mutex
type, so to integrate error-chain
with failure
just wrap dotenv::Error
: 如果你有一些不是
Sync
东西然后换成Mutex
类型,那么要将error-chain
与failure
集成,只需包装dotenv::Error
:
#[macro_use]
extern crate failure;
extern crate dotenv;
use std::sync::Mutex;
#[derive(Debug, Fail)]
#[fail(display = "oh no")]
pub struct Error(Mutex<dotenv::Error>);
fn main() {
match dotenv::dotenv() {
Err(e) => {
let err = Error(Mutex::new(e));
println!("{}", err)
}
_ => (),
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.