diff --git a/lychee-bin/src/main.rs b/lychee-bin/src/main.rs index 233c235..400b6d7 100644 --- a/lychee-bin/src/main.rs +++ b/lychee-bin/src/main.rs @@ -63,7 +63,7 @@ use std::io::{self, BufRead, BufReader, ErrorKind, Write}; use std::path::PathBuf; use std::sync::Arc; -use anyhow::{Context, Error, Result}; +use anyhow::{bail, Context, Error, Result}; use clap::Parser; use color::YELLOW; use commands::CommandParams; @@ -159,8 +159,10 @@ fn load_config() -> Result { match Config::load_from_file(config_file) { Ok(c) => opts.config.merge(c), Err(e) => { - error!("Error while loading config file {:?}: {}", config_file, e); - std::process::exit(ExitCode::ConfigFile as i32); + bail!( + "Cannot load configuration file `{}`: {e:?}", + config_file.display() + ); } } } else { @@ -253,7 +255,13 @@ fn load_cache(cfg: &Config) -> Option { fn run_main() -> Result { use std::process::exit; - let opts = load_config()?; + let opts = match load_config() { + Ok(opts) => opts, + Err(e) => { + error!("Error while loading config: {e}"); + exit(ExitCode::ConfigFile as i32); + } + }; let runtime = match opts.config.threads { Some(threads) => { diff --git a/lychee-bin/src/options.rs b/lychee-bin/src/options.rs index 00b97b6..067f5e7 100644 --- a/lychee-bin/src/options.rs +++ b/lychee-bin/src/options.rs @@ -408,8 +408,7 @@ impl Config { pub(crate) fn load_from_file(path: &Path) -> Result { // Read configuration file let contents = fs::read_to_string(path)?; - toml::from_str(&contents) - .map_err(|err| anyhow::anyhow!("Failed to parse configuration file: {}", err)) + toml::from_str(&contents).with_context(|| "Failed to parse configuration file") } /// Merge the configuration from TOML into the CLI configuration diff --git a/lychee-bin/tests/cli.rs b/lychee-bin/tests/cli.rs index cf3b61c..171a4b4 100644 --- a/lychee-bin/tests/cli.rs +++ b/lychee-bin/tests/cli.rs @@ -12,7 +12,10 @@ mod cli { use assert_json_diff::assert_json_include; use http::StatusCode; use lychee_lib::{InputSource, ResponseBody}; - use predicates::str::{contains, is_empty}; + use predicates::{ + prelude::predicate, + str::{contains, is_empty}, + }; use pretty_assertions::assert_eq; use regex::Regex; use serde::Serialize; @@ -602,7 +605,11 @@ mod cli { .arg("-") .env_clear() .assert() - .failure(); + .failure() + .stderr(predicate::str::contains("Cannot load configuration file")) + .stderr(predicate::str::contains("Failed to parse")) + .stderr(predicate::str::contains("TOML parse error")) + .stderr(predicate::str::contains("expected newline")); } #[tokio::test] diff --git a/lychee-lib/src/types/input.rs b/lychee-lib/src/types/input.rs index f2ba5f9..7cdef14 100644 --- a/lychee-lib/src/types/input.rs +++ b/lychee-lib/src/types/input.rs @@ -203,7 +203,7 @@ impl Input { InputSource::FsPath(ref path) => { if path.is_dir() { for entry in WalkDir::new(path).skip_hidden(true) - .process_read_dir(move |_, _, _, children| { + .process_read_dir(move |_, _, (), children| { children.retain(|child| { let Ok(entry) = child.as_ref() else { return true };