Skip to content

Commit

Permalink
Better TOML parsing error message
Browse files Browse the repository at this point in the history
The error handling for config loading was pretty poor.
That's because we didn't use the correct syntax to show the entire context with `anhow`.
See ["Display representations"](https://docs.rs/anyhow/latest/anyhow/struct.Error.html#display-representations).
  • Loading branch information
mre committed Jan 4, 2024
1 parent f3ac86a commit a8e9f04
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 9 deletions.
16 changes: 12 additions & 4 deletions lychee-bin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -159,8 +159,10 @@ fn load_config() -> Result<LycheeOptions> {
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 {
Expand Down Expand Up @@ -253,7 +255,13 @@ fn load_cache(cfg: &Config) -> Option<Cache> {
fn run_main() -> Result<i32> {
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) => {
Expand Down
3 changes: 1 addition & 2 deletions lychee-bin/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,7 @@ impl Config {
pub(crate) fn load_from_file(path: &Path) -> Result<Config> {
// 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
Expand Down
11 changes: 9 additions & 2 deletions lychee-bin/tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion lychee-lib/src/types/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 };

Expand Down

0 comments on commit a8e9f04

Please sign in to comment.