rtb_config/error.rs
1//! Typed errors for the config subsystem.
2
3use std::path::PathBuf;
4
5use miette::Diagnostic;
6use thiserror::Error;
7
8/// Failures surfaced by [`crate::Config`] construction and reload.
9///
10/// Every variant carries a `miette::Diagnostic` code under the
11/// `rtb::config::*` namespace so users get consistent error surfaces
12/// across the framework.
13#[derive(Debug, Error, Diagnostic)]
14#[non_exhaustive]
15pub enum ConfigError {
16 /// Figment refused the merged source set — parse failure, missing
17 /// required field, or serde type mismatch.
18 #[error("configuration error: {0}")]
19 #[diagnostic(
20 code(rtb::config::parse),
21 help("check your config file and environment variables against the schema")
22 )]
23 Parse(String),
24
25 /// User config file was referenced but could not be read.
26 #[error("could not read config file {path}: {source}")]
27 #[diagnostic(code(rtb::config::io))]
28 Io {
29 /// The path that could not be read.
30 path: PathBuf,
31 /// The underlying I/O error.
32 #[source]
33 source: std::io::Error,
34 },
35
36 /// File watcher failed — no user-file paths registered, a user
37 /// file's directory missing, OS handle limit, or an I/O error from
38 /// the underlying `notify` backend.
39 /// Only constructable when the `hot-reload` feature is enabled,
40 /// but the variant is unconditionally present so downstream
41 /// `match` arms don't need cfg-gating.
42 #[error("config watcher error: {0}")]
43 #[diagnostic(code(rtb::config::watch))]
44 Watch(String),
45
46 /// Serialisation or filesystem failure when writing the merged
47 /// value back to disk via `Config::write`. Constructable only
48 /// when the `mutable` feature is enabled, but the variant is
49 /// unconditional so consumers' `match` arms stay cfg-clean.
50 /// (`Config::write` is cfg-gated; the intra-doc link would
51 /// only resolve under `--features mutable` doc builds.)
52 #[error("config write error: {0}")]
53 #[diagnostic(code(rtb::config::write))]
54 Write(String),
55
56 /// Schema-validation failure, for a caller that validates a value
57 /// against `Config::schema`. Nothing in this crate returns it.
58 /// Unconditional for the same reason as `Write`.
59 #[error("config schema violation: {0}")]
60 #[diagnostic(code(rtb::config::schema))]
61 Schema(String),
62}
63
64impl From<figment::Error> for ConfigError {
65 fn from(value: figment::Error) -> Self {
66 Self::Parse(value.to_string())
67 }
68}