From 49a77b04047a0623f22b14fede6effd64f5e6b28 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 22 Jan 2017 03:28:38 -0800 Subject: [PATCH] Add error-chain example --- README.md | 63 +++++++++++++++++++++++++++++++++++++++++ examples/error-chain.rs | 56 ++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 examples/error-chain.rs diff --git a/README.md b/README.md index ba6c487..6479682 100644 --- a/README.md +++ b/README.md @@ -244,6 +244,69 @@ to make error handling in Rust simple and elegant. [error handling]: https://rust-lang.github.io/book/ch09-00-error-handling.html +**Example**: [`error-chain.rs`] + +[`error-chain.rs`]: examples/error-chain.rs + +```rust +#![allow(unused)] + +// `error_chain!` can recurse deeply +#![recursion_limit = "1024"] + +#[macro_use] +extern crate error_chain; + +// We'll put our errors in an `errors` module, and other modules in +// this crate will `use errors::*;` to get access to everything +// `error_chain!` creates. +mod errors { + // Create the Error, ErrorKind, ResultExt, and Result types + error_chain! { } +} + +use errors::*; + +fn main() { + if let Err(ref e) = run() { + use ::std::io::Write; + let stderr = &mut ::std::io::stderr(); + let errmsg = "Error writing to stderr"; + + writeln!(stderr, "error: {}", e).expect(errmsg); + + for e in e.iter().skip(1) { + writeln!(stderr, "caused by: {}", e).expect(errmsg); + } + + // The backtrace is not always generated. Try to run this example + // with `RUST_BACKTRACE=1`. + if let Some(backtrace) = e.backtrace() { + writeln!(stderr, "backtrace: {:?}", backtrace).expect(errmsg); + } + + ::std::process::exit(1); + } +} + +// Most functions will return the `Result` type, imported from the +// `errors` module. It is a typedef of the standard `Result` type +// for which the error type is always our own `Error`. +fn run() -> Result<()> { + use std::fs::File; + use std::env; + + // Use chain_err to attach your own context to errors + File::open("my secret file") + .chain_err(|| "unable to open my secret file")?; + + // Use the `bail!` macro to return an error Result, ala `println!` + bail!("giving up"); + + Ok(()) +} +``` + **Alternatives**: [`quick-error`] [`quick-error`]: https://docs.rs/quick-error/1.1.0/quick_error/ diff --git a/examples/error-chain.rs b/examples/error-chain.rs new file mode 100644 index 0000000..25359b3 --- /dev/null +++ b/examples/error-chain.rs @@ -0,0 +1,56 @@ +#![allow(unused)] + +// `error_chain!` can recurse deeply +#![recursion_limit = "1024"] + +#[macro_use] +extern crate error_chain; + +// We'll put our errors in an `errors` module, and other modules in +// this crate will `use errors::*;` to get access to everything +// `error_chain!` creates. +mod errors { + // Create the Error, ErrorKind, ResultExt, and Result types + error_chain! { } +} + +use errors::*; + +fn main() { + if let Err(ref e) = run() { + use ::std::io::Write; + let stderr = &mut ::std::io::stderr(); + let errmsg = "Error writing to stderr"; + + writeln!(stderr, "error: {}", e).expect(errmsg); + + for e in e.iter().skip(1) { + writeln!(stderr, "caused by: {}", e).expect(errmsg); + } + + // The backtrace is not always generated. Try to run this example + // with `RUST_BACKTRACE=1`. + if let Some(backtrace) = e.backtrace() { + writeln!(stderr, "backtrace: {:?}", backtrace).expect(errmsg); + } + + ::std::process::exit(1); + } +} + +// Most functions will return the `Result` type, imported from the +// `errors` module. It is a typedef of the standard `Result` type +// for which the error type is always our own `Error`. +fn run() -> Result<()> { + use std::fs::File; + use std::env; + + // Use chain_err to attach your own context to errors + File::open("my secret file") + .chain_err(|| "unable to open my secret file")?; + + // Use the `bail!` macro to return an error Result, ala `println!` + bail!("giving up"); + + Ok(()) +}