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

Commit c1341ea

Browse files
golddranksYamakaky
authored andcommitted
Implemented a new constructor for Error: from_err() (#126)
* Implemented a new constructor for Error: from_err(). from_err() chains another error as the cause of Error * Added a test. * Renamed Error::from_err to Error::with_chain, with_chain now takes Into<ErrorKind> instead of ErrorKind. * Updated changelog. * Moved the bounds to where clauses.
1 parent 69afe49 commit c1341ea

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Unreleased
22

3+
- [Add a new constructor for `Error`: `with_chain`.](https://github.com/brson/error-chain/pull/126)
4+
35
# 0.9.0
46

57
- Revert [Add a `Sync` bound to errors](https://github.com/brson/error-chain/pull/110)

src/error_chain.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ macro_rules! error_chain_processed {
8484
Self::from_kind(kind)
8585
}
8686

87+
fn with_chain<E, K>(error: E, kind: K)
88+
-> Self
89+
where E: ::std::error::Error + Send + 'static,
90+
K: Into<Self::ErrorKind>
91+
{
92+
Self::with_chain(error, kind)
93+
}
94+
8795
fn kind(&self) -> &Self::ErrorKind {
8896
self.kind()
8997
}
@@ -111,6 +119,18 @@ macro_rules! error_chain_processed {
111119
)
112120
}
113121

122+
/// Constructs a chained error from another error and a kind, and generates a backtrace.
123+
pub fn with_chain<E, K>(error: E, kind: K)
124+
-> $error_name
125+
where E: ::std::error::Error + Send + 'static,
126+
K: Into<$error_kind_name>
127+
{
128+
$error_name(
129+
kind.into(),
130+
$crate::State::new::<$error_name>(Box::new(error), ),
131+
)
132+
}
133+
114134
/// Returns the kind of the error.
115135
pub fn kind(&self) -> &$error_kind_name {
116136
&self.0

src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,12 @@ pub trait ChainedError: error::Error + Send + 'static {
424424
/// Constructs an error from a kind, and generates a backtrace.
425425
fn from_kind(kind: Self::ErrorKind) -> Self where Self: Sized;
426426

427+
/// Constructs a chained error from another error and a kind, and generates a backtrace.
428+
fn with_chain<E, K>(error: E, kind: K) -> Self
429+
where Self: Sized,
430+
E: ::std::error::Error + Send + 'static,
431+
K: Into<Self::ErrorKind>;
432+
427433
/// Returns the kind of the error.
428434
fn kind(&self) -> &Self::ErrorKind;
429435

tests/tests.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,3 +541,40 @@ fn types_declarations() {
541541

542542
let _: MyResult<()> = Ok(());
543543
}
544+
545+
#[test]
546+
/// Calling chain_err over a `Result` containing an error to get a chained error
547+
//// and constructing a MyError directly, passing it an error should be equivalent.
548+
fn rewrapping() {
549+
550+
use std::env::VarError::{self, NotPresent, NotUnicode};
551+
552+
error_chain! {
553+
foreign_links {
554+
VarErr(VarError);
555+
}
556+
557+
types {
558+
MyError, MyErrorKind, MyResultExt, MyResult;
559+
}
560+
}
561+
562+
let result_a_from_func: Result<String, _> = Err(VarError::NotPresent);
563+
let result_b_from_func: Result<String, _> = Err(VarError::NotPresent);
564+
565+
let our_error_a = result_a_from_func.map_err(|e| match e {
566+
NotPresent => MyError::with_chain(e, "env var wasn't provided"),
567+
NotUnicode(_) => MyError::with_chain(e, "env var was bork文字化ã"),
568+
});
569+
570+
let our_error_b = result_b_from_func.or_else(|e| match e {
571+
NotPresent => Err(e).chain_err(|| "env var wasn't provided"),
572+
NotUnicode(_) => Err(e).chain_err(|| "env var was bork文字化ã"),
573+
});
574+
575+
assert_eq!(
576+
format!("{}", our_error_a.unwrap_err()),
577+
format!("{}", our_error_b.unwrap_err())
578+
);
579+
580+
}

0 commit comments

Comments
 (0)