Error¶
Structured error type with variants for each error kind.
Overview¶
Error provides detailed error information including:
- The kind of error that occurred
- The configuration path where it happened (when applicable)
- A human-readable message with context
- Source error chain for debugging
Error Kinds¶
pub enum ErrorKind {
/// YAML or JSON syntax error
Parse,
/// Requested path doesn't exist
PathNotFound,
/// Resolver failed (env var not found, HTTP error, etc.)
Resolver(ResolverKind),
/// Schema validation failed
Validation,
/// Circular reference detected (a -> b -> a)
CircularReference,
/// Cannot convert value to requested type
TypeCoercion,
/// File I/O error
Io,
}
Handling Errors¶
Pattern Matching¶
use holoconf_core::{Config, Error, error::ErrorKind};
let result = Config::from_yaml_file("config.yaml");
match result {
Ok(config) => { /* use config */ }
Err(e) => match e.kind() {
ErrorKind::Parse => {
eprintln!("Invalid YAML/JSON: {}", e);
}
ErrorKind::Io => {
eprintln!("File error: {}", e);
}
_ => {
eprintln!("Error: {}", e);
}
}
}
Resolver Errors¶
use holoconf_core::error::{ErrorKind, ResolverKind};
match e.kind() {
ErrorKind::Resolver(ResolverKind::Env) => {
eprintln!("Environment variable not found: {}", e);
}
ErrorKind::Resolver(ResolverKind::File) => {
eprintln!("Include file not found: {}", e);
}
ErrorKind::Resolver(ResolverKind::Http) => {
eprintln!("HTTP request failed: {}", e);
}
_ => {}
}
Error Context¶
Path Information¶
Source Chain¶
// Print full error chain
let mut current: Option<&dyn std::error::Error> = Some(&e);
while let Some(err) = current {
eprintln!(" Caused by: {}", err);
current = err.source();
}
Converting to Result¶
use holoconf_core::{Config, Error};
fn load_config() -> Result<Config, Error> {
let config = Config::from_yaml_file("config.yaml")?;
config.validate(&schema)?;
Ok(config)
}
Display and Debug¶
let e: Error = /* ... */;
// User-friendly message
println!("{}", e);
// e.g., "Path 'database.host' not found"
// Debug representation with full context
println!("{:?}", e);
// e.g., Error { kind: PathNotFound, path: Some("database.host"), ... }
Common Patterns¶
Graceful Fallback¶
use holoconf_core::error::ErrorKind;
let port = match config.get_i64("database.port") {
Ok(p) => p,
Err(e) if matches!(e.kind(), ErrorKind::PathNotFound) => 5432, // default
Err(e) => return Err(e),
};
Collecting All Errors¶
let paths = ["database.host", "database.port", "app.name"];
let mut errors = Vec::new();
for path in &paths {
if let Err(e) = config.get_string(path) {
errors.push(format!("{}: {}", path, e));
}
}
if !errors.is_empty() {
eprintln!("Configuration errors:\n{}", errors.join("\n"));
}