From 9cef71b6b98ae071291fe8fb026436bcfa0f1776 Mon Sep 17 00:00:00 2001 From: Brian Donovan <1938+eventualbuddha@users.noreply.github.com> Date: Sat, 15 Jul 2023 12:13:22 -0400 Subject: [PATCH] fix(cli): improve error message for invalid config (#1200) Previously an invalid `Dioxus.toml` file would yield this error when running e.g. `dx serve`: ``` Error: Failed to load `Dioxus.toml` because: Dioxus.toml parse failed ``` This doesn't give any indication why it failed to parse. This commit updates it to include why the parsing failed, e.g.: ``` Error: Failed to load Dioxus config because: Dioxus.toml missing field `name` for key `application` at line 38 column 1 ``` I initially had it format the message to include `Dioxus.toml:38:1` to be clickable in some terminals, but the location specified didn't always seem particularly relevant to the actual problem so I left it as-is. This also fixes what I believe would be an issue on case-sensitive file systems where if `dioxus.toml` existed it would try to read `Dioxus.toml`. I'm still fairly new to Rust, so the `.as_path()` calls may not be the best way to deal with the fact that the borrow checker wouldn't let me re-use `crate_dir` and `dioxus_conf_file`. I'm open to suggestions! --- packages/cli/src/config.rs | 28 ++++++++++++++++++++-------- packages/cli/src/main.rs | 2 +- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/packages/cli/src/config.rs b/packages/cli/src/config.rs index f9117f6e5..79e6c7321 100644 --- a/packages/cli/src/config.rs +++ b/packages/cli/src/config.rs @@ -1,6 +1,9 @@ use crate::error::Result; use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, path::PathBuf}; +use std::{ + collections::HashMap, + path::{Path, PathBuf}, +}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DioxusConfig { @@ -19,27 +22,36 @@ fn default_plugin() -> toml::Value { impl DioxusConfig { pub fn load() -> crate::error::Result> { let Ok(crate_dir) = crate::cargo::crate_root() else { return Ok(None); }; + let crate_dir = crate_dir.as_path(); - // we support either `Dioxus.toml` or `Cargo.toml` let Some(dioxus_conf_file) = acquire_dioxus_toml(crate_dir) else { return Ok(None); }; + let dioxus_conf_file = dioxus_conf_file.as_path(); toml::from_str::(&std::fs::read_to_string(dioxus_conf_file)?) - .map_err(|_| crate::Error::Unique("Dioxus.toml parse failed".into())) + .map_err(|err| { + let error_location = dioxus_conf_file + .strip_prefix(crate_dir) + .unwrap_or(dioxus_conf_file) + .display(); + crate::Error::Unique(format!("{error_location} {err}")) + }) .map(Some) } } -fn acquire_dioxus_toml(dir: PathBuf) -> Option { +fn acquire_dioxus_toml(dir: &Path) -> Option { // prefer uppercase - if dir.join("Dioxus.toml").is_file() { - return Some(dir.join("Dioxus.toml")); + let uppercase_conf = dir.join("Dioxus.toml"); + if uppercase_conf.is_file() { + return Some(uppercase_conf); } // lowercase is fine too - if dir.join("dioxus.toml").is_file() { - return Some(dir.join("Dioxus.toml")); + let lowercase_conf = dir.join("dioxus.toml"); + if lowercase_conf.is_file() { + return Some(lowercase_conf); } None diff --git a/packages/cli/src/main.rs b/packages/cli/src/main.rs index f2007aa43..86e90db96 100644 --- a/packages/cli/src/main.rs +++ b/packages/cli/src/main.rs @@ -14,7 +14,7 @@ async fn main() -> anyhow::Result<()> { set_up_logging(); let _dioxus_config = DioxusConfig::load() - .map_err(|e| anyhow!("Failed to load `Dioxus.toml` because: {e}"))? + .map_err(|e| anyhow!("Failed to load Dioxus config because: {e}"))? .unwrap_or_else(|| { log::warn!("You appear to be creating a Dioxus project from scratch; we will use the default config"); DioxusConfig::default()