fraiseql_error/config.rs
1use std::path::PathBuf;
2
3/// Errors that occur while loading or validating FraiseQL configuration.
4#[derive(Debug, thiserror::Error)]
5pub enum ConfigError {
6 /// No configuration file was found at the expected location(s).
7 #[error("Configuration file not found")]
8 NotFound,
9
10 /// The configuration file was found but could not be read from disk.
11 #[error("Failed to read configuration file {path}: {source}")]
12 ReadError {
13 /// Path to the file that could not be read.
14 path: PathBuf,
15 /// Underlying I/O error.
16 source: std::io::Error,
17 },
18
19 /// The configuration file was read successfully but contains invalid TOML
20 /// or does not conform to the expected schema.
21 #[error("Failed to parse configuration: {source}")]
22 ParseError {
23 /// The TOML deserialisation error.
24 #[from]
25 source: toml::de::Error,
26 },
27
28 /// A configuration value failed a semantic validation rule (e.g. a port
29 /// number that is out of range, or conflicting options).
30 #[error("Validation error in {field}: {message}")]
31 ValidationError {
32 /// Dot-separated path to the invalid configuration field.
33 field: String,
34 /// Human-readable description of why the value is invalid.
35 message: String,
36 },
37
38 /// A required environment variable was not set at startup.
39 #[error("Missing required environment variable: {name}")]
40 MissingEnvVar {
41 /// Name of the missing environment variable.
42 name: String,
43 },
44
45 /// Several configuration errors were collected together (e.g. during a
46 /// full-file validation pass) and are reported as a single error.
47 #[error("Multiple configuration errors")]
48 MultipleErrors {
49 /// All individual errors that were encountered.
50 errors: Vec<ConfigError>,
51 },
52}
53
54impl ConfigError {
55 /// Returns a short, stable error code string suitable for API responses and
56 /// structured logging.
57 pub const fn error_code(&self) -> &'static str {
58 match self {
59 Self::NotFound => "config_not_found",
60 Self::ReadError { .. } => "config_read_error",
61 Self::ParseError { .. } => "config_parse_error",
62 Self::ValidationError { .. } => "config_validation_error",
63 Self::MissingEnvVar { .. } => "config_missing_env",
64 Self::MultipleErrors { .. } => "config_multiple_errors",
65 }
66 }
67}