如何使错误链错误与失败错误兼容?

时间:2018-05-13 22:59:08

标签: error-handling rust

给出以下代码:

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);

由于error-chain(v0.11,最新版本)无法保证其包装错误为Syncopen PR to fix the issue),因此我收到错误消息{{1没有为Sync实现:

dotenv::Error

为了使这些类型能够很好地协同工作,我可以使用的最小量的样板/工作量是多少?我能够提出的最短的事情是添加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` 新类型,以便我可以在ErrorWrapper上实施Error

Arc<Mutex<ERROR_CHAIN_TYPE>>

这是正确的方法吗?对于那些不需要它的东西,转换成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` 会有更少的代码/运行时成本吗?

1 个答案:

答案 0 :(得分:1)

我唯一可以建议删除Arc类型。

如果您的某些内容不是Sync,那么请将其换成Mutex类型 将error-chainfailure集成,只需打包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)
        }
        _ => (),
    }
}