From b1d559ea00da03a6f7d2a7bd71f7bcceb5ae8af2 Mon Sep 17 00:00:00 2001 From: Carson McManus Date: Mon, 21 Feb 2022 11:57:19 -0500 Subject: [PATCH] add non-zero exit codes when unrecoverable errors occur. --- src/errors.rs | 7 +++++ src/main.rs | 74 +++++++++++++++++++++++++++------------------------ 2 files changed, 46 insertions(+), 35 deletions(-) create mode 100644 src/errors.rs diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..f63f420 --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,7 @@ +use thiserror::Error; + +#[derive(Debug, Error)] +pub(crate) enum UserError { + #[error("User aborted the operation.")] + Aborted +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 293c358..aa2f0c0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,7 @@ extern crate ring; mod accountmanager; mod demos; mod encryption; +mod errors; mod tui; fn cli() -> App<'static, 'static> { @@ -126,6 +127,16 @@ fn cli() -> App<'static, 'static> { } fn main() { + std::process::exit(match run() { + Ok(_) => 0, + Err(e) => { + error!("{:?}", e); + 255 + } + }); +} + +fn run() -> anyhow::Result<()> { let matches = cli().get_matches(); let verbosity = matches.occurrences_of("verbosity") as usize + 2; @@ -140,7 +151,7 @@ fn main() { if demo_matches.is_present("demo-conf-menu") { demos::demo_confirmation_menu(); } - return; + return Ok(()); } if let Some(completion_matches) = matches.subcommand_matches("completion") { cli().gen_completions_to( @@ -148,7 +159,7 @@ fn main() { Shell::from_str(completion_matches.value_of("shell").unwrap()).unwrap(), &mut std::io::stdout(), ); - return; + return Ok(()); } let mafiles_dir = if matches.occurrences_of("mafiles-path") > 0 { @@ -167,24 +178,16 @@ fn main() { ) { 'n' => { info!("Aborting!"); - return; + return Err(errors::UserError::Aborted.into()); } _ => {} } - std::fs::create_dir_all(mafiles_dir).expect("failed to create directory"); + std::fs::create_dir_all(mafiles_dir)?; manifest = accountmanager::Manifest::new(path.as_path()); - manifest.save(&None).expect("Failed to save manifest"); + manifest.save(&None)?; } else { - match accountmanager::Manifest::load(path.as_path()) { - Ok(m) => { - manifest = m; - } - Err(e) => { - error!("Could not load manifest: {}", e); - return; - } - } + manifest = accountmanager::Manifest::load(path.as_path())?; } let mut passkey: Option = matches.value_of("passkey").map(|s| s.into()); @@ -203,7 +206,7 @@ fn main() { } Err(e) => { error!("Could not load accounts: {}", e); - return; + return Err(e.into()); } } } @@ -213,7 +216,7 @@ fn main() { print!("Username: "); let username = tui::prompt(); if manifest.account_exists(&username) { - error!( + bail!( "Account {} already exists in manifest, remove it first", username ); @@ -231,7 +234,7 @@ fn main() { } Err(AccountLinkError::MustRemovePhoneNumber) => { println!("There is already a phone number on this account, please remove it and try again."); - return; + bail!("There is already a phone number on this account, please remove it and try again."); } Err(AccountLinkError::MustProvidePhoneNumber) => { println!("Enter your phone number in the following format: +1 123-456-7890"); @@ -240,7 +243,7 @@ fn main() { } Err(AccountLinkError::AuthenticatorPresent) => { println!("An authenticator is already present on this account."); - return; + bail!("An authenticator is already present on this account."); } Err(AccountLinkError::MustConfirmEmail) => { println!("Check your email and click the link."); @@ -251,7 +254,7 @@ fn main() { "Failed to link authenticator. Account has not been linked. {}", err ); - return; + return Err(err.into()); } } } @@ -264,7 +267,7 @@ fn main() { "Just in case, here is the account info. Save it somewhere just in case!\n{:?}", manifest.accounts.last().unwrap().lock().unwrap() ); - return; + return Err(err.into()); } } @@ -292,12 +295,12 @@ fn main() { tries += 1; if tries >= 30 { error!("Failed to finalize: unable to generate valid 2fa codes"); - return; + bail!("Failed to finalize: unable to generate valid 2fa codes"); } } Err(err) => { error!("Failed to finalize: {}", err); - return; + return Err(err.into()); } } } @@ -310,7 +313,7 @@ fn main() { "Failed to save manifest, but we were able to save it before. {}", err ); - return; + return Err(err); } } @@ -319,7 +322,7 @@ fn main() { account.revocation_code ); - return; + return Ok(()); } else if let Some(import_matches) = matches.subcommand_matches("import") { for file_path in import_matches.values_of("files").unwrap() { match manifest.import_account(file_path.into()) { @@ -327,13 +330,13 @@ fn main() { info!("Imported account: {}", file_path); } Err(err) => { - error!("Failed to import account: {} {}", file_path, err); + bail!("Failed to import account: {} {}", file_path, err); } } } - manifest.save(&passkey).expect("Failed to save manifest."); - return; + manifest.save(&passkey)?; + return Ok(()); } else if matches.is_present("encrypt") { if passkey.is_none() { loop { @@ -349,14 +352,14 @@ fn main() { for entry in &mut manifest.entries { entry.encryption = Some(accountmanager::EntryEncryptionParams::generate()); } - manifest.save(&passkey).expect("Failed to save manifest."); - return; + manifest.save(&passkey)?; + return Ok(()); } else if matches.is_present("decrypt") { for entry in &mut manifest.entries { entry.encryption = None; } - manifest.save(&passkey).expect("Failed to save manifest."); - return; + manifest.save(&passkey)?; + return Ok(()); } let mut selected_accounts: Vec>> = vec![]; @@ -401,7 +404,7 @@ fn main() { } Err(_) => { info!("failed to get trade confirmations, asking user to log in"); - do_login(&mut account).expect("Failed to log in"); + do_login(&mut account)?; } } } @@ -432,7 +435,7 @@ fn main() { } } - manifest.save(&passkey).expect("Failed to save manifest"); + manifest.save(&passkey)?; } else if let Some(_) = matches.subcommand_matches("remove") { println!( "This will remove the mobile authenticator from {} accounts: {}", @@ -448,7 +451,7 @@ fn main() { 'y' => {} _ => { info!("Aborting!"); - return; + return Err(errors::UserError::Aborted.into()); } } @@ -489,7 +492,7 @@ fn main() { manifest.remove_account(account_name); } - manifest.save(&passkey).expect("Failed to save manifest."); + manifest.save(&passkey)?; } else { let server_time = steamapi::get_server_time(); debug!("Time used to generate codes: {}", server_time); @@ -503,6 +506,7 @@ fn main() { println!("{}", code); } } + Ok(()) } fn do_login(account: &mut SteamGuardAccount) -> anyhow::Result<()> {