From 6bd1904e4372c83bdada63acfcead1a046caa6c0 Mon Sep 17 00:00:00 2001 From: Yi Hyunjoon Date: Mon, 14 Sep 2020 22:48:37 +0900 Subject: [PATCH 1/3] Replace`failure` with `anyhow` in tutorial --- Cargo.lock | 10 ++++++++-- Cargo.toml | 1 + src/tutorial/errors-exit.rs | 7 +++---- src/tutorial/errors.md | 32 +++++++++++--------------------- src/tutorial/testing/Cargo.toml | 3 +-- src/tutorial/testing/src/main.rs | 7 +++---- 6 files changed, 27 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6c504cba..1db8fb91 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,6 +4,7 @@ name = "CLAiR" version = "0.1.0" dependencies = [ + "anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "convey 0.2.0 (git+https://github.com/killercup/convey?rev=1e356d4634821764e58f842e9140a74c76b781b8)", "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -23,9 +24,8 @@ dependencies = [ name = "CLAiR-testing" version = "0.1.0" dependencies = [ + "anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "assert_cmd 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "exitfailure 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "predicates 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -47,6 +47,11 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "anyhow" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "arc-swap" version = "0.4.4" @@ -941,6 +946,7 @@ dependencies = [ [metadata] "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" "checksum arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" "checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" "checksum assert_cmd 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b7ac5c260f75e4e4ba87b7342be6edcecbcb3eb6741a0507fda7ad115845cc65" diff --git a/Cargo.toml b/Cargo.toml index f22504a7..3178ea99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,7 @@ members = [ structopt = "0.2.10" failure = "0.1.3" exitfailure = "0.5.1" +anyhow = "1.0" indicatif = "0.10.1" log = "0.4.6" env_logger = "0.6.0" diff --git a/src/tutorial/errors-exit.rs b/src/tutorial/errors-exit.rs index a3373a3f..c0046f8c 100644 --- a/src/tutorial/errors-exit.rs +++ b/src/tutorial/errors-exit.rs @@ -1,10 +1,9 @@ -use failure::ResultExt; -use exitfailure::ExitFailure; +use anyhow::{Context, Result}; -fn main() -> Result<(), ExitFailure> { +fn main() -> Result<()> { let path = "test.txt"; let content = std::fs::read_to_string(path) - .with_context(|_| format!("could not read file `{}`", path))?; + .with_context(|| format!("could not read file `{}`", path))?; println!("file content: {}", content); Ok(()) } diff --git a/src/tutorial/errors.md b/src/tutorial/errors.md index 6b1103d3..f5d6295e 100644 --- a/src/tutorial/errors.md +++ b/src/tutorial/errors.md @@ -206,32 +206,20 @@ This pattern is in fact very common. It has one problem, though: We don't store the original error, only its string representation. -The often used [`failure`] library has a neat solution for that: +The often used [`anyhow`] library has a neat solution for that: Similar to our `CustomError` type, -it has a [`Context`] type +it has a [`Context`] trait that contains a description as well as the original error. -The library also brings with it an extension trait ([`ResultExt`]) -that adds [`context()`] and [`with_context()`] methods to `Result`. - -[`failure`]: https://docs.rs/failure -[`Context`]: https://docs.rs/failure/0.1.7/failure/struct.Context.html -[`ResultExt`]: https://docs.rs/failure/0.1.7/failure/trait.ResultExt.html -[`context()`]: https://docs.rs/failure/0.1.7/failure/trait.ResultExt.html#tymethod.context -[`with_context()`]: https://docs.rs/failure/0.1.7/failure/trait.ResultExt.html#tymethod.with_context - -To turn these wrapped error types -into something that humans will actually want to read, -we can further add the [`exitfailure`] crate, -and use its type as the return type of our `main` function. - -Let's first import the crates by adding -`failure = "0.1.7"` and `exitfailure = "0.5.1"` to the `[dependencies]` section + +[`anyhow`]: https://docs.rs/anyhow +[`Context`]: https://docs.rs/anyhow/1.0/anyhow/trait.Context.html + +Let's first import `anyhow` crate by adding +`anyhow = "1.0"` to the `[dependencies]` section of our `Cargo.toml` file. The full example will then look like this: -[`exitfailure`]: https://docs.rs/exitfailure - ```rust,ignore {{#include errors-exit.rs}} ``` @@ -240,5 +228,7 @@ This will print an error: ```text Error: could not read file `test.txt` -Info: caused by No such file or directory (os error 2) + +Caused by: + No such file or directory (os error 2) ``` diff --git a/src/tutorial/testing/Cargo.toml b/src/tutorial/testing/Cargo.toml index 74013014..0fbe1f7e 100644 --- a/src/tutorial/testing/Cargo.toml +++ b/src/tutorial/testing/Cargo.toml @@ -6,8 +6,7 @@ edition = "2018" [dependencies] structopt = "0.2.10" -failure = "0.1.3" -exitfailure = "0.5.1" +anyhow = "1.0" [dev-dependencies] assert_cmd = "0.10" diff --git a/src/tutorial/testing/src/main.rs b/src/tutorial/testing/src/main.rs index ea56926e..e6f04770 100644 --- a/src/tutorial/testing/src/main.rs +++ b/src/tutorial/testing/src/main.rs @@ -1,6 +1,5 @@ use structopt::StructOpt; -use failure::ResultExt; -use exitfailure::ExitFailure; +use anyhow::{Context, Result}; /// Search for a pattern in a file and display the lines that contain it. #[derive(StructOpt)] @@ -12,10 +11,10 @@ struct Cli { path: std::path::PathBuf, } -fn main() -> Result<(), ExitFailure> { +fn main() -> Result<()> { let args = Cli::from_args(); let content = std::fs::read_to_string(&args.path) - .with_context(|_| format!("could not read file `{}`", args.path.display()))?; + .with_context(|| format!("could not read file `{}`", args.path.display()))?; find_matches(&content, &args.pattern, &mut std::io::stdout()); From c716c47df6ef2ab4f964f129e8122a24b7c8b32a Mon Sep 17 00:00:00 2001 From: Yi Hyunjoon Date: Tue, 15 Sep 2020 18:30:52 +0900 Subject: [PATCH 2/3] Update src/tutorial/errors.md --- src/tutorial/errors.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tutorial/errors.md b/src/tutorial/errors.md index f5d6295e..ac44ef0f 100644 --- a/src/tutorial/errors.md +++ b/src/tutorial/errors.md @@ -208,13 +208,14 @@ We don't store the original error, only its string representation. The often used [`anyhow`] library has a neat solution for that: Similar to our `CustomError` type, -it has a [`Context`] trait -that contains a description as well as the original error. +its [`Context`] trait can be used to add a description. +Additionally, it also keeps the original error, +so we get a "chain" of error messages pointing out the root cause. [`anyhow`]: https://docs.rs/anyhow [`Context`]: https://docs.rs/anyhow/1.0/anyhow/trait.Context.html -Let's first import `anyhow` crate by adding +Let's first import the `anyhow` crate by adding `anyhow = "1.0"` to the `[dependencies]` section of our `Cargo.toml` file. From 334c8e9e9c068fe56afee426f11348b6a817ff43 Mon Sep 17 00:00:00 2001 From: Yi Hyunjoon Date: Tue, 15 Sep 2020 18:32:06 +0900 Subject: [PATCH 3/3] Replace`failure` with `anyhow` in signals-channels --- src/in-depth/signals-channels.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/in-depth/signals-channels.rs b/src/in-depth/signals-channels.rs index 76a5bcbd..38241415 100644 --- a/src/in-depth/signals-channels.rs +++ b/src/in-depth/signals-channels.rs @@ -1,5 +1,6 @@ use std::time::Duration; use crossbeam_channel::{bounded, tick, Receiver, select}; +use anyhow::Result; fn ctrl_channel() -> Result, ctrlc::Error> { let (sender, receiver) = bounded(100); @@ -10,7 +11,7 @@ fn ctrl_channel() -> Result, ctrlc::Error> { Ok(receiver) } -fn main() -> Result<(), exitfailure::ExitFailure> { +fn main() -> Result<()> { let ctrl_c_events = ctrl_channel()?; let ticks = tick(Duration::from_secs(1));