Skip to main content

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}