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