Skip to content

Commit c021627

Browse files
committed
Improve error when config file is missing
When no config file exists, the config library builds from defaults alone, which fails with a confusing "missing field" error for version-specific settings like ohttp_relays. Detect whether any config file was actually loaded and, if not, append a hint telling the user where to create one or to use CLI arguments instead. Closes payjoin#855
1 parent 3647419 commit c021627

File tree

1 file changed

+38
-6
lines changed

1 file changed

+38
-6
lines changed

payjoin-cli/src/app/config.rs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,23 @@ impl Config {
132132

133133
config = handle_subcommands(config, cli)?;
134134

135+
let mut config_file_found = false;
136+
let mut config_file_paths = Vec::new();
137+
135138
if let Some(config_dir) = dirs::config_dir() {
136139
let global_config_path = config_dir.join(CONFIG_DIR).join("config.toml");
140+
if global_config_path.exists() {
141+
config_file_found = true;
142+
}
143+
config_file_paths.push(global_config_path.display().to_string());
137144
config = config.add_source(File::from(global_config_path).required(false));
138145
}
139146

147+
let local_config_path = std::path::Path::new("config.toml");
148+
if local_config_path.exists() {
149+
config_file_found = true;
150+
}
151+
config_file_paths.push("config.toml (current directory)".to_string());
140152
config = config.add_source(File::new("config.toml", FileFormat::Toml).required(false));
141153
let built_config = config.build()?;
142154

@@ -165,10 +177,20 @@ impl Config {
165177

166178
config.version = Some(VersionConfig::V1(v1))
167179
}
168-
Err(e) =>
180+
Err(e) => {
181+
let hint = if config_file_found {
182+
String::new()
183+
} else {
184+
format!(
185+
"\nNo config file found. Searched: {}. \
186+
Create a config.toml or provide configuration via CLI arguments.",
187+
config_file_paths.join(", ")
188+
)
189+
};
169190
return Err(ConfigError::Message(format!(
170-
"Valid V1 configuration is required for BIP78 mode: {e}"
171-
))),
191+
"Valid V1 configuration is required for BIP78 mode: {e}{hint}"
192+
)));
193+
}
172194
}
173195
}
174196
#[cfg(not(feature = "v1"))]
@@ -181,10 +203,20 @@ impl Config {
181203
{
182204
match built_config.get::<V2Config>("v2") {
183205
Ok(v2) => config.version = Some(VersionConfig::V2(v2)),
184-
Err(e) =>
206+
Err(e) => {
207+
let hint = if config_file_found {
208+
String::new()
209+
} else {
210+
format!(
211+
"\nNo config file found. Searched: {}. \
212+
Create a config.toml or provide configuration via CLI arguments.",
213+
config_file_paths.join(", ")
214+
)
215+
};
185216
return Err(ConfigError::Message(format!(
186-
"Valid V2 configuration is required for BIP77 mode: {e}"
187-
))),
217+
"Valid V2 configuration is required for BIP77 mode: {e}{hint}"
218+
)));
219+
}
188220
}
189221
}
190222
#[cfg(not(feature = "v2"))]

0 commit comments

Comments
 (0)