diff --git a/src/basics.md b/src/basics.md
index dbd112a..6e0b587 100644
--- a/src/basics.md
+++ b/src/basics.md
@@ -25,6 +25,7 @@
| [Define and operate on a type represented as a bitfield][ex-bitflags] | [![bitflags-badge]][bitflags] | [![cat-no-std-badge]][cat-no-std] |
| [Access a file randomly using a memory map][ex-random-file-access] | [![memmap-badge]][memmap] | [![cat-filesystem-badge]][cat-filesystem] |
| [Check number of logical cpu cores][ex-check-cpu-cores] | [![num_cpus-badge]][num_cpus] | [![cat-hardware-support-badge]][cat-hardware-support] |
+| [Avoid discarding errors during error conversions][ex-error-chain-avoid-discarding] | [![error-chain-badge]][error-chain] | [![cat-rust-patterns-badge]][cat-rust-patterns] |
| [Obtain backtrace of complex error scenarios][ex-error-chain-backtrace] | [![error-chain-badge]][error-chain] | [![cat-rust-patterns-badge]][cat-rust-patterns] |
| [Measure elapsed time][ex-measure-elapsed-time] | [![std-badge]][std] | [![cat-time-badge]][cat-time] |
| [Convert date to UNIX timestamp and vice versa][ex-convert-datetime-timestamp] | [![chrono-badge]][chrono] | [![cat-date-and-time-badge]][cat-date-and-time] |
@@ -1145,6 +1146,74 @@ fn main() {
}
```
+[ex-error-chain-avoid-discarding]: #ex-error-chain-avoid-discarding
+
+## Avoid discarding errors during error conversions
+
+[![error-chain-badge]][error-chain] [![cat-rust-patterns-badge]][cat-rust-patterns]
+
+[Matching] on different error types returned by a function is possible
+and relatively compact with [error-chain] crate. To do so,
+[`ErrorKind`] is used to determine the error type.
+
+To illustrate the error matching, a random integer generator web
+service will be queried via [reqwest] and then the response will be
+parsed. Errors can be generated by the Rust standard library,
+[reqwest] and by the web service. [`foreign_links`] are used for well
+defined Rust errors. The `errors` block of the `error_chain!` macro is
+used to create an additional [`ErrorKind`] variant for the web service
+error. Finally, a regular `match` can be used to react differently
+according to the raised error.
+
+```rust
+#[macro_use]
+extern crate error_chain;
+extern crate reqwest;
+
+use std::io::Read;
+
+error_chain! {
+ foreign_links {
+ Io(std::io::Error);
+ Reqwest(reqwest::Error);
+ ParseIntError(std::num::ParseIntError);
+ }
+
+ errors { RandomResponseError(t: String) }
+}
+
+fn parse_response(mut response: reqwest::Response) -> Result {
+ let mut body = String::new();
+ response.read_to_string(&mut body)?;
+ body.pop();
+ body.parse::()
+ .chain_err(|| ErrorKind::RandomResponseError(body))
+}
+
+fn run() -> Result<()> {
+ let url =
+ format!("https://www.random.org/integers/?num=1&min=0&max=10&col=1&base=10&format=plain");
+ let response = reqwest::get(&url)?;
+ let random_value: u32 = parse_response(response)?;
+
+ println!("a random number between 0 and 10: {}", random_value);
+
+ Ok(())
+}
+
+fn main() {
+ if let Err(error) = run() {
+ match *error.kind() {
+ ErrorKind::Io(_) => println!("Standard IO error: {:?}", error),
+ ErrorKind::Reqwest(_) => println!("Reqwest error: {:?}", error),
+ ErrorKind::ParseIntError(_) => println!("Standard parse int error: {:?}", error),
+ ErrorKind::RandomResponseError(_) => println!("User defined error: {:?}", error),
+ _ => println!("Other error: {:?}", error),
+ }
+ }
+}
+```
+
[ex-error-chain-backtrace]: #ex-error-chain-backtrace
## Obtain backtrace of complex error scenarios
@@ -1514,14 +1583,17 @@ fn main() {
[`digest::Context`]: https://docs.rs/ring/*/ring/digest/struct.Context.html
[`digest::Digest`]: https://docs.rs/ring/*/ring/digest/struct.Digest.html
[`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
+[`ErrorKind`]: https://docs.rs/error-chain/*/error_chain/example_generated/enum.ErrorKind.html
[`File::create`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.create
[`File::open`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.open
[`File::try_clone`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.try_clone
[`File`]: https://doc.rust-lang.org/std/fs/struct.File.html
+[`foreign_links`]: https://docs.rs/error-chain/*/error_chain/#foreign-links
[`HashMap`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html
[`hmac::Signature`]: https://docs.rs/ring/*/ring/hmac/struct.Signature.html
[`IndependentSample::ind_sample`]: https://doc.rust-lang.org/rand/rand/distributions/trait.IndependentSample.html#tymethod.ind_sample
[`Lines`]: https://doc.rust-lang.org/std/io/struct.Lines.html
+[Matching]:https://docs.rs/error-chain/*/error_chain/#matching-errors
[`Mmap::map`]: https://docs.rs/memmap/*/memmap/struct.Mmap.html#method.map
[`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html
[`MutexGuard`]: https://doc.rust-lang.org/std/sync/struct.MutexGuard.html
diff --git a/src/intro.md b/src/intro.md
index e031a0b..117c3c8 100644
--- a/src/intro.md
+++ b/src/intro.md
@@ -43,6 +43,7 @@ community. It needs and welcomes help. For details see
| [Define and operate on a type represented as a bitfield][ex-bitflags] | [![bitflags-badge]][bitflags] | [![cat-no-std-badge]][cat-no-std] |
| [Access a file randomly using a memory map][ex-random-file-access] | [![memmap-badge]][memmap] | [![cat-filesystem-badge]][cat-filesystem] |
| [Check number of logical cpu cores][ex-check-cpu-cores] | [![num_cpus-badge]][num_cpus] | [![cat-hardware-support-badge]][cat-hardware-support] |
+| [Avoid discarding errors during error conversions][ex-error-chain-avoid-discarding] | [![error-chain-badge]][error-chain] | [![cat-rust-patterns-badge]][cat-rust-patterns] |
| [Obtain backtrace of complex error scenarios][ex-error-chain-backtrace] | [![error-chain-badge]][error-chain] | [![cat-rust-patterns-badge]][cat-rust-patterns] |
| [Measure elapsed time][ex-measure-elapsed-time] | [![std-badge]][std] | [![cat-time-badge]][cat-time] |
| [Convert date to UNIX timestamp and vice versa][ex-convert-datetime-timestamp] | [![chrono-badge]][chrono] | [![cat-date-and-time-badge]][cat-date-and-time] |
@@ -172,6 +173,7 @@ community. It needs and welcomes help. For details see
[ex-csv-serde]: encoding.html#ex-csv-serde
[ex-datetime-arithmetic]: basics.html#ex-datetime-arithmetic
[ex-dedup-filenames]: app.html#ex-dedup-filenames
+[ex-error-chain-avoid-discarding]: basics.html#ex-error-chain-avoid-discarding
[ex-error-chain-backtrace]: basics.html#ex-error-chain-backtrace
[ex-examine-date-and-time]: basics.html#ex-examine-date-and-time
[ex-extract-hashtags]: basics.html#ex-extract-hashtags