etl_core/config/error.rs
1//! Configuration errors.
2
3use std::path::PathBuf;
4
5/// Why a pipeline configuration could not be loaded or is invalid.
6///
7/// Every variant carries enough context to act on without opening the
8/// source code: file paths, YAML paths (`source.kafka.brokers`), or
9/// line/column positions.
10#[derive(Debug, thiserror::Error)]
11#[non_exhaustive]
12pub enum ConfigError {
13 /// The configuration file could not be read.
14 #[error("failed to read config file `{path}`: {source}")]
15 Io {
16 /// File that could not be read.
17 path: PathBuf,
18 /// Underlying I/O error.
19 #[source]
20 source: std::io::Error,
21 },
22
23 /// `${VAR}` environment interpolation failed before parsing.
24 #[error("environment interpolation failed at line {line}, column {column}: {reason}")]
25 Interpolation {
26 /// 1-based line of the offending `$`.
27 line: usize,
28 /// 1-based byte column of the offending `$`.
29 column: usize,
30 /// What went wrong (undefined variable, malformed syntax, ...).
31 reason: String,
32 },
33
34 /// The YAML did not match the expected schema.
35 #[error("invalid configuration at `{path}`: {source}")]
36 Parse {
37 /// Dotted YAML path to the offending value (best effort; `.` when
38 /// the error is not attributable to a specific field).
39 path: String,
40 /// Underlying YAML/serde error.
41 #[source]
42 source: serde_yaml::Error,
43 },
44
45 /// A component section (`source:`, `sink:`, `deserializer:`) is not a
46 /// single-key mapping, or its opaque body failed to deserialize into
47 /// the component's typed config.
48 #[error("{context}: {message}")]
49 Component {
50 /// Where in the config the problem is, e.g. `source.kafka.brokers`.
51 context: String,
52 /// What went wrong.
53 message: String,
54 },
55
56 /// The YAML parsed but violates a cross-field rule.
57 #[error("invalid configuration: {0}")]
58 Validation(String),
59}