diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-03-09 11:42:45 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-03-09 18:09:50 +0100 |
commit | 391a4b92c977cd64dfd131f3e29b0bc8d756d064 (patch) | |
tree | b5b96ff935853cef9ee22e01890c248a791e724e /tool | |
parent | 58d662c6d37dd1b0dccd4d0ce30290b8ede408e9 (diff) |
Switch from failure to anyhow.
- Use the anyhow crate instead of failure to implement the dynamic
side of our error handling. anyhow::Error derefs to dyn
std::error::Error, allowing better interoperability with other
stdlib-based error handling libraries.
- Fixes #444.
Diffstat (limited to 'tool')
-rw-r--r-- | tool/Cargo.toml | 2 | ||||
-rw-r--r-- | tool/src/commands/decrypt.rs | 13 | ||||
-rw-r--r-- | tool/src/commands/key.rs | 32 | ||||
-rw-r--r-- | tool/src/commands/mod.rs | 19 | ||||
-rw-r--r-- | tool/src/commands/sign.rs | 12 | ||||
-rw-r--r-- | tool/src/sq.rs | 25 |
6 files changed, 36 insertions, 67 deletions
diff --git a/tool/Cargo.toml b/tool/Cargo.toml index 10832d54..3139bc9a 100644 --- a/tool/Cargo.toml +++ b/tool/Cargo.toml @@ -27,9 +27,9 @@ sequoia-autocrypt = { path = "../autocrypt", version = "0.15" } sequoia-core = { path = "../core", version = "0.15" } sequoia-net = { path = "../net", version = "0.15" } sequoia-store = { path = "../store", version = "0.15" } +anyhow = "1" chrono = "0.4" clap = "2.32.0" -failure = "0.1.2" itertools = "0.8" prettytable-rs = "0.8.0" rpassword = "=4.0.3" diff --git a/tool/src/commands/decrypt.rs b/tool/src/commands/decrypt.rs index 65b9d579..964fd6c8 100644 --- a/tool/src/commands/decrypt.rs +++ b/tool/src/commands/decrypt.rs @@ -1,5 +1,5 @@ use crossterm::terminal; -use failure::{self, ResultExt}; +use anyhow::Context as _; use std::collections::HashMap; use std::io; use rpassword; @@ -253,7 +253,7 @@ impl<'a> DecryptionHelper for Helper<'a> { if skesks.is_empty() { return - Err(failure::err_msg("No key to decrypt message")); + Err(anyhow::anyhow!("No key to decrypt message")); } // Finally, try to decrypt using the SKESKs. @@ -289,14 +289,7 @@ pub fn decrypt(ctx: &Context, policy: &dyn Policy, mapping: &mut store::Mapping, let mut decryptor = Decryptor::from_reader(policy, input, helper, None) .context("Decryption failed")?; - io::copy(&mut decryptor, output) - .map_err(|e| if e.get_ref().is_some() { - // Wrapped failure::Error. Recover it. - failure::Error::from_boxed_compat(e.into_inner().unwrap()) - } else { - // Plain io::Error. - e.into() - }).context("Decryption failed")?; + io::copy(&mut decryptor, output).context("Decryption failed")?; let helper = decryptor.into_helper(); if let Some(dumper) = helper.dumper.as_ref() { diff --git a/tool/src/commands/key.rs b/tool/src/commands/key.rs index bbde9ceb..688633a8 100644 --- a/tool/src/commands/key.rs +++ b/tool/src/commands/key.rs @@ -1,5 +1,4 @@ -use failure; -use failure::Fail; +use anyhow::Context as _; use clap::ArgMatches; use itertools::Itertools; use std::time::{SystemTime, Duration}; @@ -66,7 +65,7 @@ pub fn generate(m: &ArgMatches, force: bool) -> Result<()> { builder = builder.set_cipher_suite(CipherSuite::Cv25519); } Some(ref cs) => { - return Err(format_err!("Unknown cipher suite '{}'", cs)); + return Err(anyhow::anyhow!("Unknown cipher suite '{}'", cs)); } None => panic!("argument has a default value"), } @@ -79,7 +78,7 @@ pub fn generate(m: &ArgMatches, force: bool) -> Result<()> { (false, true) => { /* no signing subkey */ } (true, true) => { return Err( - format_err!("Conflicting arguments --can-sign and --cannot-sign")); + anyhow::anyhow!("Conflicting arguments --can-sign and --cannot-sign")); } } @@ -101,12 +100,12 @@ pub fn generate(m: &ArgMatches, force: bool) -> Result<()> { (None, true) => { /* no encryption subkey */ } (Some(_), true) => { return Err( - format_err!("Conflicting arguments --can-encrypt and \ + anyhow::anyhow!("Conflicting arguments --can-encrypt and \ --cannot-encrypt")); } (Some(ref cap), false) => { return Err( - format_err!("Unknown encryption capability '{}'", cap)); + anyhow::anyhow!("Unknown encryption capability '{}'", cap)); } } @@ -119,7 +118,7 @@ pub fn generate(m: &ArgMatches, force: bool) -> Result<()> { if p0 == p1 { builder = builder.set_password(Some(p0)); } else { - return Err(failure::err_msg("Passwords do not match.")); + return Err(anyhow::anyhow!("Passwords do not match.")); } } @@ -136,7 +135,7 @@ pub fn generate(m: &ArgMatches, force: bool) -> Result<()> { ("-".to_string(), rp.to_string()), (Some("-"), None) => return Err( - format_err!("Missing arguments: --rev-cert is mandatory \ + anyhow::anyhow!("Missing arguments: --rev-cert is mandatory \ if --export is '-'.")), (Some(ref kp), None) => (kp.to_string(), format!("{}.rev", kp)), @@ -146,7 +145,7 @@ pub fn generate(m: &ArgMatches, force: bool) -> Result<()> { (kp.to_string(), rp.to_string()), _ => return Err( - format_err!("Conflicting arguments --rev-cert and \ + anyhow::anyhow!("Conflicting arguments --rev-cert and \ --export")), }; @@ -178,7 +177,7 @@ pub fn generate(m: &ArgMatches, force: bool) -> Result<()> { } } else { return Err( - format_err!("Saving generated key to the store isn't implemented \ + anyhow::anyhow!("Saving generated key to the store isn't implemented \ yet.")); } @@ -205,19 +204,18 @@ fn parse_duration(expiry: &str) -> Result<Duration> { let junk = expiry.collect::<String>(); if digits == "" { - return Err(format_err!( + return Err(anyhow::anyhow!( "--expiry: missing count \ (try: '2y' for 2 years)")); } let count = match digits.parse::<i32>() { Ok(count) if count < 0 => - return Err(format_err!( + return Err(anyhow::anyhow!( "--expiry: Expiration can't be in the past")), Ok(count) => count as u64, Err(err) => - return Err(err.context( - "--expiry: count is out of range").into()), + return Err(err).context("--expiry: count is out of range"), }; let factor = match suffix { @@ -226,19 +224,19 @@ fn parse_duration(expiry: &str) -> Result<Duration> { Some('w') | Some('W') => 7 * SECONDS_IN_DAY, Some('d') | Some('D') => SECONDS_IN_DAY, None => - return Err(format_err!( + return Err(anyhow::anyhow!( "--expiry: missing suffix \ (try: '{}y', '{}m', '{}w' or '{}d' instead)", digits, digits, digits, digits)), Some(suffix) => - return Err(format_err!( + return Err(anyhow::anyhow!( "--expiry: invalid suffix '{}' \ (try: '{}y', '{}m', '{}w' or '{}d' instead)", suffix, digits, digits, digits, digits)), }; if junk != "" { - return Err(format_err!( + return Err(anyhow::anyhow!( "--expiry: contains trailing junk ('{:?}') \ (try: '{}{}')", junk, count, factor)); diff --git a/tool/src/commands/mod.rs b/tool/src/commands/mod.rs index a925d362..8c2fd516 100644 --- a/tool/src/commands/mod.rs +++ b/tool/src/commands/mod.rs @@ -1,4 +1,4 @@ -use failure::{self, ResultExt}; +use anyhow::Context as _; use std::cmp::Ordering; use std::collections::{HashMap, HashSet}; use std::fs::File; @@ -78,7 +78,7 @@ fn get_signing_keys(certs: &[openpgp::Cert], p: &dyn Policy, } } - return Err(failure::err_msg( + return Err(anyhow::anyhow!( format!("Found no suitable signing key on {}", tsk))); } @@ -108,7 +108,7 @@ pub fn encrypt(policy: &dyn Policy, } if certs.len() + passwords.len() == 0 { - return Err(failure::format_err!( + return Err(anyhow::anyhow!( "Neither recipient nor password given")); } @@ -128,7 +128,7 @@ pub fn encrypt(policy: &dyn Policy, count += 1; } if count == 0 { - return Err(failure::format_err!( + return Err(anyhow::anyhow!( "Key {} has no suitable encryption key", cert)); } } @@ -394,7 +394,7 @@ impl<'a> VerificationHelper for VHelper<'a> { Ok(()) } else { self.print_status(); - Err(failure::err_msg("Verification failed")) + Err(anyhow::anyhow!("Verification failed")) } } } @@ -413,14 +413,7 @@ pub fn verify(ctx: &Context, policy: &dyn Policy, Verifier::from_reader(policy, input, helper, None)? }; - io::copy(&mut verifier, output) - .map_err(|e| if e.get_ref().is_some() { - // Wrapped failure::Error. Recover it. - failure::Error::from_boxed_compat(e.into_inner().unwrap()) - } else { - // Plain io::Error. - e.into() - })?; + io::copy(&mut verifier, output)?; verifier.into_helper().print_status(); Ok(()) diff --git a/tool/src/commands/sign.rs b/tool/src/commands/sign.rs index 89b97a10..9a8e6819 100644 --- a/tool/src/commands/sign.rs +++ b/tool/src/commands/sign.rs @@ -1,4 +1,4 @@ -use failure::{self, ResultExt}; +use anyhow::Context as _; use std::fs; use std::io; use std::path::PathBuf; @@ -60,7 +60,7 @@ fn sign_data(policy: &dyn Policy, match packet { Packet::Signature(sig) => sigs.push(sig), p => return Err( - failure::err_msg( + anyhow::anyhow!( format!("{} in detached signature", p.tag())) .context("Invalid detached signature").into()), } @@ -91,7 +91,7 @@ fn sign_data(policy: &dyn Policy, let mut keypairs = super::get_signing_keys(&secrets, policy, time)?; if keypairs.is_empty() { - return Err(failure::format_err!("No signing keys found")); + return Err(anyhow::anyhow!("No signing keys found")); } // When extending a detached signature, prepend any existing @@ -166,7 +166,7 @@ fn sign_message_(policy: &dyn Policy, { let mut keypairs = super::get_signing_keys(&secrets, policy, time)?; if keypairs.is_empty() { - return Err(failure::format_err!("No signing keys found")); + return Err(anyhow::anyhow!("No signing keys found")); } let mut sink = Message::new(output); @@ -205,7 +205,7 @@ fn sign_message_(policy: &dyn Policy, match pp.packet { Packet::PKESK(_) | Packet::SKESK(_) => - return Err(failure::err_msg( + return Err(anyhow::anyhow!( "Signing encrypted data is not implemented")), Packet::Literal(_) => @@ -223,7 +223,7 @@ fn sign_message_(policy: &dyn Policy, // If you do implement this, there is a half-disabled test // in tests/sq-sign.rs. Packet::CompressedData(_) if seen_signature => - return Err(failure::err_msg( + return Err(anyhow::anyhow!( "Signing a compress-then-sign message is not implemented")), _ => (), diff --git a/tool/src/sq.rs b/tool/src/sq.rs index 6b188e0e..421dadae 100644 --- a/tool/src/sq.rs +++ b/tool/src/sq.rs @@ -2,8 +2,6 @@ extern crate clap; #[macro_use] -extern crate failure; -#[macro_use] extern crate prettytable; extern crate rpassword; extern crate tempfile; @@ -12,7 +10,7 @@ extern crate itertools; extern crate tokio_core; use crossterm::terminal; -use failure::ResultExt; +use anyhow::Context as _; use prettytable::{Table, Cell, Row}; use std::fs::{File, OpenOptions}; use std::io::{self, Write}; @@ -65,7 +63,7 @@ fn create_or_stdout(f: Option<&str>, force: bool) .open(f) .context("Failed to create output file")?)) } else { - Err(failure::err_msg( + Err(anyhow::anyhow!( format!("File {:?} exists, use --force to overwrite", p))) } } @@ -213,7 +211,7 @@ fn help_warning(arg: &str) { } } -fn real_main() -> Result<()> { +fn main() -> Result<()> { let policy = &P::new(); let matches = sq_cli::build().get_matches(); @@ -392,7 +390,7 @@ fn real_main() -> Result<()> { let ac = autocrypt::AutocryptHeader::new_sender( policy, &cert, - &addr.ok_or(failure::err_msg( + &addr.ok_or(anyhow::anyhow!( "No well-formed primary userid found, use \ --address to specify one"))?, m.value_of("prefer-encrypt").expect("has default"))?; @@ -767,7 +765,7 @@ fn parse_iso8601(s: &str, pad_date_with: chrono::NaiveTime) return Ok(DateTime::from_utc(d.and_time(pad_date_with), Utc)); } } - Err(failure::format_err!("Malformed ISO8601 timestamp: {}", s)) + Err(anyhow::anyhow!("Malformed ISO8601 timestamp: {}", s)) } #[test] @@ -795,16 +793,3 @@ fn test_parse_iso8601() { parse_iso8601("2017031", z).unwrap(); // parse_iso8601("2017", z).unwrap(); // ditto } - -fn main() { - if let Err(e) = real_main() { - let mut cause = e.as_fail(); - eprint!("{}", cause); - while let Some(c) = cause.cause() { - eprint!(":\n {}", c); - cause = c; - } - eprintln!(); - exit(2); - } -} |