Skip to content
This repository was archived by the owner on Aug 16, 2021. It is now read-only.

Added support for 'Sync' compatible error #300

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 0.12.5
- [Added the 'Sync' trait so that errors can propogate across threads (e.g. usage within tokio)](https://github.com/john-sharratt/error-chain)

# 0.12.4
- [executable bits to support build platform linters](https://github.com/rust-lang-nursery/error-chain/pull/289)

Expand Down
8 changes: 5 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
[package]
name = "error-chain"
version = "0.12.4" # remember to update html_root_url
version = "0.12.5" # remember to update html_root_url
authors = [ "Brian Anderson <[email protected]>",
"Paul Colomiets <[email protected]>",
"Colin Kiegel <[email protected]>",
"Yamakaky <[email protected]>",
"Andrew Gauger <[email protected]>"]
"Andrew Gauger <[email protected]>",
"Johnathan Sharratt <[email protected]>"]
description = "Yet another error boilerplate library."
keywords = ["error"]
categories = ["rust-patterns"]
Expand All @@ -17,8 +18,9 @@ readme = "README.md"
license = "MIT/Apache-2.0"

[features]
default = ["backtrace", "example_generated"]
default = ["backtrace", "example_generated", "sync"]
example_generated = []
sync = []

[dependencies]
backtrace = { version = "0.3.3", optional = true }
Expand Down
17 changes: 10 additions & 7 deletions src/error_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,10 @@ macro_rules! impl_error_chain_processed {
pub $crate::State,
);

impl $crate::ChainedError for $error_name {
impl $crate::trait_alias::TraitCheck for $error_name { }

impl $crate::ChainedError for $error_name
{
type ErrorKind = $error_kind_name;

fn new(kind: $error_kind_name, state: $crate::State) -> $error_name {
Expand All @@ -231,7 +234,7 @@ macro_rules! impl_error_chain_processed {

fn with_chain<E, K>(error: E, kind: K)
-> Self
where E: ::std::error::Error + Send + 'static,
where E: $crate::trait_alias::StdError + 'static,
K: Into<Self::ErrorKind>
{
Self::with_chain(error, kind)
Expand Down Expand Up @@ -273,15 +276,15 @@ macro_rules! impl_error_chain_processed {
/// Constructs a chained error from another error and a kind, and generates a backtrace.
pub fn with_chain<E, K>(error: E, kind: K)
-> $error_name
where E: ::std::error::Error + Send + 'static,
where E: $crate::trait_alias::StdError + 'static,
K: Into<$error_kind_name>
{
$error_name::with_boxed_chain(Box::new(error), kind)
}

/// Construct a chained error from another boxed error and a kind, and generates a backtrace
#[allow(unknown_lints, bare_trait_objects)]
pub fn with_boxed_chain<K>(error: Box<::std::error::Error + Send>, kind: K)
pub fn with_boxed_chain<K>(error: $crate::trait_alias::BoxError, kind: K)
-> $error_name
where K: Into<$error_kind_name>
{
Expand All @@ -290,7 +293,7 @@ macro_rules! impl_error_chain_processed {
$crate::State::new::<$error_name>(error, ),
)
}

/// Returns the kind of the error.
pub fn kind(&self) -> &$error_kind_name {
&self.0
Expand Down Expand Up @@ -426,7 +429,7 @@ macro_rules! impl_error_chain_processed {
EK: Into<$error_kind_name>;
}

impl<T, E> $result_ext_name<T> for ::std::result::Result<T, E> where E: ::std::error::Error + Send + 'static {
impl<T, E> $result_ext_name<T> for ::std::result::Result<T, E> where E: $crate::trait_alias::StdError + 'static {
fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
where F: FnOnce() -> EK,
EK: Into<$error_kind_name> {
Expand Down
12 changes: 8 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,8 @@ pub use quick_main::ExitCode;
mod backtrace;
#[cfg(feature = "example_generated")]
pub mod example_generated;
#[doc(hidden)]
pub mod trait_alias;
pub use backtrace::Backtrace;
#[doc(hidden)]
pub use backtrace::InternalBacktrace;
Expand Down Expand Up @@ -592,7 +594,9 @@ impl<'a> Iterator for Iter<'a> {

/// This trait is implemented on all the errors generated by the `error_chain`
/// macro.
pub trait ChainedError: error::Error + Send + 'static {
pub trait ChainedError: crate::trait_alias::StdError + 'static
where Self: crate::trait_alias::TraitCheck
{
/// Associated kind type.
type ErrorKind;

Expand All @@ -605,7 +609,7 @@ pub trait ChainedError: error::Error + Send + 'static {
fn with_chain<E, K>(error: E, kind: K) -> Self
where
Self: Sized,
E: ::std::error::Error + Send + 'static,
E: crate::trait_alias::StdError + 'static,
K: Into<Self::ErrorKind>;

/// Returns the kind of the error.
Expand Down Expand Up @@ -675,7 +679,7 @@ where
#[allow(unknown_lints, bare_trait_objects)]
pub struct State {
/// Next error in the error chain.
pub next_error: Option<Box<error::Error + Send>>,
pub next_error: Option<trait_alias::BoxError>,
/// Backtrace for the current error.
pub backtrace: InternalBacktrace,
}
Expand All @@ -692,7 +696,7 @@ impl Default for State {
impl State {
/// Creates a new State type
#[allow(unknown_lints, bare_trait_objects)]
pub fn new<CE: ChainedError>(e: Box<error::Error + Send>) -> State {
pub fn new<CE: ChainedError>(e: trait_alias::BoxError) -> State {
let backtrace = CE::extract_backtrace(&*e).unwrap_or_else(InternalBacktrace::new);
State {
next_error: Some(e),
Expand Down
23 changes: 23 additions & 0 deletions src/trait_alias.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#[doc(hidden)]
#[cfg(feature = "sync")]
pub trait StdError: std::error::Error + Send + Sync { }
#[doc(hidden)]
#[cfg(not(feature = "sync"))]
pub trait StdError: std::error::Error + Send { }
#[cfg(feature = "sync")]
impl<E> StdError for E where E: std::error::Error + Send + Sync { }
#[cfg(not(feature = "sync"))]
impl<E> StdError for E where E: std::error::Error + Send { }
#[doc(hidden)]
#[cfg(feature = "sync")]
pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
#[doc(hidden)]
#[cfg(not(feature = "sync"))]
pub type BoxError = Box<dyn std::error::Error + Send>;

#[doc(hidden)]
#[cfg(feature = "sync")]
pub trait TraitCheck: Send + Sync { }
#[doc(hidden)]
#[cfg(not(feature = "sync"))]
pub trait TraitCheck: Send { }