Summary:
Add a type to explicitly model a causal chain of errors, akin to
error_chain. This looks a lot like Context, but is intended to show the entire
stack of errors rather than deciding that only the top-level one is
interesting.
This adds a `ChainExt` trait, which adds a `.chain_ext(OuterError)` method to
add another step to the causal chain. This is implemented for:
- `F` where `F: Fail`
- `Error`
- `Result<_, F>` where `F: Fail`
- `Result<_, Error>`
- `Future`/`Stream<Error=F>` where `F: Fail`
- `Future`/`Stream<Error=Error>`
- `Chain`
Using it is simple:
```
let res = something_faily().chain_err(LocalError::new("Something amiss"))?;
```
where `something_faily()` returns any of the above types.
(This is done by adding an extra dummy marker type parameter to the `ChainExt`
trait so that it can avoid problems with the coherence rules - thanks for the idea @[100000771202578:kulshrax]!)
Reviewed By: lukaspiatkowski
Differential Revision: D9394192
fbshipit-source-id: 0817844d283b3900d2555f526c2683231ca7fe12
Summary:
Add a pair of macros to make downcasting errors less tedious:
```
let res = err_downcast! {
err, // failure::Error
foo: FooError => { println!("err is an FooError! {:?}", foo) },
bar: BarError => { println!("err is a BarError! {:?}", bar) },
};
```
`err_downcast` takes `failure::Error` and deconstructs it into one of the
desired types and returns `Ok(match action)`, or returning it as `Err(Error)`
if nothing matches.
`err_downcast_ref` takes `&failure::Error` and gives a reference type. It
returns `Some(match action)` or `None` if nothing matches.
The error types are required to implement `failure::Fail`.
`err_downcast_ref` also matches each error type `E` as `Context<E>`.
Reviewed By: lukaspiatkowski
Differential Revision: D9394193
fbshipit-source-id: c56d91362d5bed8ab3e254bc44bb6f8a0eb376a2