From 2bdf5d768f0125895b8078a2b681bcddd3ac8af2 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Wed, 10 Jun 2020 13:00:10 -0600 Subject: [PATCH] feat: use `anyhow` for more structured error messages and better error reporting flexibility This significantly changes the structure of potential output of top-level errors. Before, errors that have a `source` were printed on a single line, with the `source` omitted. Now, an error with a `source` will be printed like: ``` Error: <`Display` impl of error> Caused by: <`Display` impl of `source` error> ``` If there are multiple `source` errors in a chain, then it will be of the form: ``` Error: <`Display` impl of error> Caused by: 0: <`Display` impl of first `source` error> 1: <`Display` impl of `source` of `source` error> # etc. ``` Now, in practice this never happened before, since the only error type that ever could return from `::run` was `std::io::Error`, which has no `source`. However, `source`s can start being added if, say, future work involved using `anyhow::Context::context` or custom errors that implement `std::Error::source` are added to the codebase. I believe this is a good choice going forward, but I definitely want to foster discussion and acceptance for it in the open first! --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/bin/hexyl.rs | 8 +++++--- src/lib.rs | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a61396..ca22315 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,6 +16,11 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "anyhow" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "atty" version = "0.2.14" @@ -58,6 +63,7 @@ name = "hexyl" version = "0.8.0" dependencies = [ "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", @@ -118,6 +124,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +"checksum anyhow 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f" "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" diff --git a/Cargo.toml b/Cargo.toml index 5c42e2c..214480d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ edition = "2018" [dependencies] ansi_term = "0.12" +anyhow = "1.0.31" atty = "0.2" libc = "0.2" diff --git a/src/bin/hexyl.rs b/src/bin/hexyl.rs index eb43151..7025a71 100644 --- a/src/bin/hexyl.rs +++ b/src/bin/hexyl.rs @@ -9,9 +9,11 @@ use clap::{App, AppSettings, Arg}; use atty::Stream; +use anyhow::{anyhow, Error as AnyhowError}; + use hexyl::{BorderStyle, Input, Printer}; -fn run() -> Result<(), Box> { +fn run() -> Result<(), AnyhowError> { let app = App::new(crate_name!()) .setting(AppSettings::ColorAuto) .setting(AppSettings::ColoredHelp) @@ -165,7 +167,7 @@ fn run() -> Result<(), Box> { let mut printer = Printer::new(&mut stdout_lock, show_color, border_style, squeeze); printer.display_offset(display_offset); - printer.print_all(&mut reader)?; + printer.print_all(&mut reader).map_err(|e| anyhow!(e))?; Ok(()) } @@ -189,7 +191,7 @@ fn main() { _ => (), } } else { - eprintln!("Error: {}", err); + eprintln!("Error: {:?}", err); } std::process::exit(1); } diff --git a/src/lib.rs b/src/lib.rs index fba1eb3..2bdbdc3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -408,7 +408,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> { pub fn print_all( &mut self, mut reader: Reader, - ) -> Result<(), Box> { + ) -> Result<(), Box> { let mut buffer = [0; BUFFER_SIZE]; 'mainloop: loop { let size = reader.read(&mut buffer)?;