From 1cec37a577c0a645ffabe004700a74b016a563c4 Mon Sep 17 00:00:00 2001 From: Ilesh Date: Sat, 6 Nov 2021 19:45:57 +0530 Subject: [PATCH] Switch to `thiserror` for error handling --- CHANGELOG.md | 4 ++ Cargo.lock | 9 ++-- Cargo.toml | 6 +-- src/main.rs | 9 +++- src/util/ferium_error.rs | 96 ++++++++++++---------------------------- 5 files changed, 50 insertions(+), 74 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 761d02c..1c79a3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog for Ferium +## [3.7.2] - 06.11.2021 + +- Switched to `thiserror` for error handling + ## [3.7.1] - 06.11.2021 - Ferium now compiles successfully on Linux diff --git a/Cargo.lock b/Cargo.lock index 42cfc5b..ef85b5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -296,7 +296,8 @@ dependencies = [ [[package]] name = "clap" version = "3.0.0-beta.5" -source = "git+https://github.com/clap-rs/clap/#6b0c49e8400d9bbf0a03afd7026e8d9f68c3a34b" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feff3878564edb93745d58cf63e17b63f24142506e7a20c87a5521ed7bfb1d63" dependencies = [ "atty", "bitflags", @@ -314,7 +315,8 @@ dependencies = [ [[package]] name = "clap_derive" version = "3.0.0-beta.5" -source = "git+https://github.com/clap-rs/clap/#6b0c49e8400d9bbf0a03afd7026e8d9f68c3a34b" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b15c6b4f786ffb6192ffe65a36855bc1fc2444bcd0945ae16748dcd6ed7d0d3" dependencies = [ "heck", "proc-macro-error", @@ -466,7 +468,7 @@ dependencies = [ [[package]] name = "ferium" -version = "3.7.1" +version = "3.7.2" dependencies = [ "ansi_term", "bytes", @@ -480,6 +482,7 @@ dependencies = [ "serde", "serde_json", "shellexpand", + "thiserror", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index d84b4eb..5ed0c6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ferium" -version = "3.7.1" +version = "3.7.2" edition = "2021" authors = ["theRookieCoder "] description = "Ferium is an easy to use manager for Minecraft mods on Modrinth and Github Releases" @@ -12,15 +12,15 @@ publish = false [dependencies] # Use `rustls` rather than OpenSSL reqwest = { version = "0", default-features = false, features = ["json", "rustls-tls"] } -# Use bleeding edge version of `clap` -clap = { git = "https://github.com/clap-rs/clap/", features = ["yaml"] } tokio = { version = "1", features = ["rt-multi-thread", "macros"] } +clap = { version = "3.0.0-beta", features = ["yaml"] } serde = { version = "1", features = ["derive"] } fancy-regex = "0" shellexpand = "2" serde_json = "1" ansi_term = "0" dialoguer = "0" +thiserror = "1" ferinth = "1" online = "3" bytes = "1" diff --git a/src/main.rs b/src/main.rs index 6571158..cd64e2a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,14 @@ use util::{ }; #[tokio::main] -async fn main() -> FResult<()> { +async fn main() { + if let Some(err) = actual_main().await.err() { + println!("{}", err); + std::process::exit(1); + } +} + +async fn actual_main() -> FResult<()> { // Get the command to execute from Clap // This also displays help, version let command = cli::get_subcommand()?; diff --git a/src/util/ferium_error.rs b/src/util/ferium_error.rs index cd94e5f..5f62ff4 100644 --- a/src/util/ferium_error.rs +++ b/src/util/ferium_error.rs @@ -1,86 +1,48 @@ -use std::{ - convert::From, - fmt::{Debug, Formatter}, -}; +use std::fmt::Debug; +use thiserror::Error; pub type FResult = std::result::Result; +#[derive(Error, Debug)] pub enum FError { /// The config file does not contain mods or repos + #[error("Your config file is empty! Run `ferium help` to see how to add mods or repositories")] EmptyConfigFile, /// An HTTP(S) request returned with an error - ReqwestError { error: reqwest::Error }, + #[error("Failed to send/process an HTTP(S) request due to {}", .0)] + ReqwestError(#[from] reqwest::Error), /// Failure to unwrap an Option, akin to `NullPointerError`s + #[error("Could not access an expected value")] OptionError, /// Failed to parse a regular expression - RegexError, + #[error("Failed to parse regular expression")] + RegexError(#[from] fancy_regex::Error), /// A JSON error occured - JsonError { - category: serde_json::error::Category, - }, + #[error("{}", match .0.classify() { + serde_json::error::Category::Syntax => { + "Syntax error encountered in JSON file" + }, + serde_json::error::Category::Data => { + "Non matching type while deserialising JSON" + }, + serde_json::error::Category::Eof => { + "Unexpected end of file while reading JSON" + }, + serde_json::error::Category::Io => { + "Encountered an Input/Output error while handling JSON" + }, + })] + JsonError(#[from] serde_json::Error), /// An HTTP(S) request encountered an error + #[error("An HTTP(S) request returned an error, {}", message)] HTTPError { message: String }, /// An I/O error occured - IOError { description: String }, + #[error("Encountered an input/output error, {}", .0.to_string())] + IOError(#[from] std::io::Error), /// The program is running on an unsupported device + #[error("The device you are currently running on is unsupported by Ferium")] InvalidDeviceError, /// The application should print `message` and quit (gracefully) + #[error("{}", message)] Quit { message: String }, } - -impl Debug for FError { - fn fmt(&self, fmt: &mut Formatter) -> Result<(), std::fmt::Error> { - match self { - FError::EmptyConfigFile => write!(fmt, "Your config file is empty! Run `ferium help` to see how to add mods or repositories"), - FError::HTTPError { message } => write!(fmt, "An HTTP(S) request returned an error, {}", message), - FError::InvalidDeviceError => write!(fmt, "The device you are currently running on is unsupported by Ferium"), - FError::IOError {description} => write!(fmt, "Encountered an input/output error, {}", description), - FError::JsonError { category } => match category { - serde_json::error::Category::Syntax => { - write!(fmt, "Syntax error encountered in JSON file") - }, - serde_json::error::Category::Data => { - write!(fmt, "Non matching type while deserialising JSON") - }, - serde_json::error::Category::Eof => { - write!(fmt, "Unexpected end of file while reading JSON") - }, - serde_json::error::Category::Io => { - write!(fmt, "Encountered an Input/Output error while handling JSON") - }, - }, - FError::OptionError => write!(fmt, "Could not access an expected value"), - FError::Quit { message } => write!(fmt, "{}", message), - FError::RegexError => write!(fmt, "Failed to parse regular expression"), - FError::ReqwestError { error }=> write!(fmt, "Failed to send/process an HTTP(S) request due to {}", error), - } - } -} - -impl From for FError { - fn from(err: reqwest::Error) -> Self { - Self::ReqwestError { error: err } - } -} - -impl From for FError { - fn from(_: fancy_regex::Error) -> Self { - Self::RegexError - } -} - -impl From for FError { - fn from(err: std::io::Error) -> Self { - Self::IOError { - description: err.to_string(), - } - } -} - -impl From for FError { - fn from(err: serde_json::Error) -> Self { - Self::JsonError { - category: err.classify(), - } - } -}