Skip to content

Commit 444f3b2

Browse files
committed
use error_chain for error handling
1 parent 24a3666 commit 444f3b2

File tree

8 files changed

+52
-81
lines changed

8 files changed

+52
-81
lines changed

Diff for: Cargo.lock

+17
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ image = "0.23.10"
3030
regex = "1"
3131
futures = "0.3.6"
3232
tokio = { version = "0.2.22", features = ["full"] }
33+
error-chain = "0.12"
3334

3435
[target.'cfg(windows)'.dependencies]
3536
ansi_term = "0.12"

Diff for: src/error.rs

+12-36
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,15 @@
1-
/// Custom error type
2-
#[derive(Debug)]
3-
pub enum Error {
4-
/// Sourcecode could be located
5-
SourceCodeNotFound,
6-
/// Git is not installed or did not function properly
7-
GitNotInstalled,
8-
/// Did not find any git data in the directory
9-
NoGitData,
10-
/// An IO error occoured while reading ./
11-
ReadDirectory,
12-
/// Not in a Git Repo
13-
NotGitRepo,
14-
/// Error while getting branch info
15-
BareGitRepo,
16-
/// Repository is a bare git repo
17-
ReferenceInfoError,
18-
/// Image probably doesn't exist or has wrong format
19-
ImageLoadError,
20-
/// Could not initialize the license detector
21-
LicenseDetectorError,
22-
}
1+
use colored::Colorize;
2+
use error_chain::error_chain;
3+
use std::io::Write;
234

24-
impl std::fmt::Display for Error {
25-
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
26-
let content = match self {
27-
Error::SourceCodeNotFound => "Could not find any source code in this directory",
28-
Error::GitNotInstalled => "Git failed to execute",
29-
Error::NoGitData => "Could not retrieve git configuration data",
30-
Error::ReadDirectory => "Could not read directory",
31-
Error::NotGitRepo => "Could not find a valid git repo on the current path",
32-
Error::BareGitRepo => "Unable to run onefetch on bare git repos",
33-
Error::ReferenceInfoError => "Error while retrieving reference information",
34-
Error::ImageLoadError => "Could not load the specified image",
35-
Error::LicenseDetectorError => "Could not initialize the license detector",
36-
};
37-
write!(f, "{}", content)
5+
error_chain! {
6+
foreign_links {
7+
Clap(::clap::Error) #[cfg(feature = "application")];
8+
Io(::std::io::Error);
9+
ParseIntError(::std::num::ParseIntError);
3810
}
3911
}
12+
13+
pub fn default_error_handler(error: &Error, output: &mut dyn Write) {
14+
writeln!(output, "{}: {}", "[onefetch error]".red(), error).ok();
15+
}

Diff for: src/exit_codes.rs

-14
This file was deleted.

Diff for: src/info.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use {
22
crate::{
3+
error::*,
34
language::Language,
45
license::Detector,
56
options::Options,
6-
{AsciiArt, CommitInfo, Error},
7+
{AsciiArt, CommitInfo},
78
},
89
colored::{Color, ColoredString, Colorize},
910
git2::Repository,
@@ -13,8 +14,6 @@ use {
1314
tokio::process::Command,
1415
};
1516

16-
type Result<T> = std::result::Result<T, crate::Error>;
17-
1817
const LICENSE_FILES: [&str; 3] = ["LICENSE", "LICENCE", "COPYING"];
1918

2019
#[derive(Default)]
@@ -377,8 +376,8 @@ impl std::fmt::Display for Info {
377376
impl Info {
378377
#[tokio::main]
379378
pub async fn new(config: Options) -> Result<Info> {
380-
let repo = Repository::discover(&config.path).map_err(|_| Error::NotGitRepo)?;
381-
let workdir = repo.workdir().ok_or(Error::BareGitRepo)?;
379+
let repo = Repository::discover(&config.path).chain_err(||"Could not find a valid git repo on the current path")?;
380+
let workdir = repo.workdir().chain_err(||"Unable to run onefetch on bare git repo")?;
382381
let workdir_str = workdir.to_str().unwrap();
383382
let (languages_stats, number_of_lines) =
384383
Language::get_language_stats(workdir_str, &config.excluded)?;
@@ -486,7 +485,7 @@ impl Info {
486485
}
487486

488487
async fn get_repo_name_and_url(repo: &Repository) -> (String, String) {
489-
let config = repo.config().map_err(|_| Error::NoGitData);
488+
let config = repo.config().chain_err(|| "Could not retrieve git configuration data");
490489
let mut remote_url = String::new();
491490
let mut repository_name = String::new();
492491

@@ -519,9 +518,9 @@ impl Info {
519518
}
520519

521520
async fn get_current_commit_info(repo: &Repository) -> Result<CommitInfo> {
522-
let head = repo.head().map_err(|_| Error::ReferenceInfoError)?;
523-
let head_oid = head.target().ok_or(Error::ReferenceInfoError)?;
524-
let refs = repo.references().map_err(|_| Error::ReferenceInfoError)?;
521+
let head = repo.head().chain_err(|| "Error while retrieving reference information")?;
522+
let head_oid = head.target().ok_or("Error while retrieving reference information")?;
523+
let refs = repo.references().chain_err(|| "Error while retrieving reference information")?;
525524
let refs_info = refs
526525
.filter_map(|reference| match reference {
527526
Ok(reference) => match (reference.target(), reference.shorthand()) {
@@ -754,7 +753,7 @@ impl Info {
754753
let detector = Detector::new()?;
755754

756755
let mut output = fs::read_dir(dir)
757-
.map_err(|_| Error::ReadDirectory)?
756+
.chain_err(|| "Could not read directory")?
758757
.filter_map(std::result::Result::ok)
759758
.map(|entry| entry.path())
760759
.filter(|entry| {

Diff for: src/language.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use {
2-
crate::{Error, Result},
2+
crate::error::*,
33
colored::Color,
44
regex::Regex,
55
std::collections::HashMap,
@@ -185,7 +185,7 @@ impl Language {
185185
) -> Result<(Vec<(Language, f64)>, usize)> {
186186
let tokei_langs = project_languages(&dir, ignored_directories);
187187
let languages_stat =
188-
Language::get_languages_stat(&tokei_langs).ok_or(Error::SourceCodeNotFound)?;
188+
Language::get_languages_stat(&tokei_langs).ok_or("ErrorKind::SourceCodeNotFound()")?;
189189
let mut stat_vec: Vec<(_, _)> = languages_stat.into_iter().collect();
190190
stat_vec.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap().reverse());
191191
let loc = get_total_loc(&tokei_langs);

Diff for: src/license.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use askalono::{Store, TextData};
22

3-
use crate::Error;
4-
5-
type Result<T> = std::result::Result<T, Error>;
3+
use crate::error::*;
64

75
static CACHE_DATA: &[u8] = include_bytes!("../resources/licenses/cache.bin.zstd");
86
const MIN_THRESHOLD: f32 = 0.8;
@@ -15,7 +13,7 @@ impl Detector {
1513
pub fn new() -> Result<Self> {
1614
Store::from_cache(CACHE_DATA)
1715
.map(|store| Self { store })
18-
.map_err(|_| Error::LicenseDetectorError)
16+
.map_err(|_| "Could not initialize the license detector".into())
1917
}
2018

2119
pub fn analyze(&self, text: &str) -> Option<String> {

Diff for: src/main.rs

+9-15
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,33 @@
1+
// `error_chain!` can recurse deeply
2+
#![recursion_limit = "1024"]
3+
14
use {
25
ascii_art::AsciiArt,
3-
colored::Colorize,
46
commit_info::CommitInfo,
5-
error::Error,
6-
exit_codes::ExitCode,
7+
error::*,
78
info::Info,
89
language::Language,
910
process::{Command, Stdio},
10-
std::{convert::From, env, io::Write, process, result, str::FromStr},
11+
std::{convert::From, env, process, str::FromStr},
1112
strum::IntoEnumIterator,
1213
};
1314

1415
mod ascii_art;
1516
mod clap_app;
1617
mod commit_info;
1718
mod error;
18-
mod exit_codes;
1919
mod image_backends;
2020
mod info;
2121
mod language;
2222
mod license;
2323
mod options;
2424

25-
type Result<T> = result::Result<T, Error>;
26-
2725
fn run() -> Result<()> {
2826
#[cfg(windows)]
2927
let _ = ansi_term::enable_ansi_support();
3028

3129
if !is_git_installed() {
32-
return Err(Error::GitNotInstalled);
30+
return Err("Git failed to execute!".into());
3331
}
3432

3533
let matches = clap_app::build_app().get_matches_from(env::args_os());
@@ -45,7 +43,7 @@ fn run() -> Result<()> {
4543
};
4644

4745
let image = if let Some(image_path) = matches.value_of("image") {
48-
Some(image::open(image_path).map_err(|_| Error::ImageLoadError)?)
46+
Some(image::open(image_path).chain_err(|| "Could not load the specified image")?)
4947
} else {
5048
None
5149
};
@@ -110,20 +108,16 @@ fn main() {
110108
let result = run();
111109
match result {
112110
Ok(_) => {
113-
process::exit(ExitCode::Success.into());
111+
process::exit(0);
114112
}
115113
Err(error) => {
116114
let stderr = std::io::stderr();
117115
default_error_handler(&error, &mut stderr.lock());
118-
process::exit(ExitCode::GeneralError.into());
116+
process::exit(1);
119117
}
120118
}
121119
}
122120

123-
pub fn default_error_handler(error: &Error, output: &mut dyn Write) {
124-
writeln!(output, "{}: {}", "[onefetch error]".red(), error).ok();
125-
}
126-
127121
fn is_git_installed() -> bool {
128122
Command::new("git")
129123
.arg("--version")

0 commit comments

Comments
 (0)