ch_config/config/
error.rs1use std::io;
2use std::path::PathBuf;
3
4use thiserror::Error;
5
6#[derive(Debug, Error)]
8pub enum ConfigError {
9 #[error("invalid configuration field `{field}`: {message}")]
11 Validation {
12 field: &'static str,
14 message: &'static str,
16 },
17
18 #[error("failed to load environment file `{path}`")]
20 Environment {
21 path: PathBuf,
23 #[source]
25 source: EnvironmentFileError,
26 },
27
28 #[error("configuration files have already been loaded for this process")]
30 EnvironmentAlreadyLoaded,
31
32 #[error("configuration variable `{variable}` conflicts with `{variable}_FILE`")]
34 VariableConflict {
35 variable: &'static str,
37 },
38
39 #[error("configuration variable `{variable}` is not set")]
41 VariableMissing {
42 variable: String,
44 },
45
46 #[error("configuration variable `{variable}` must be valid Unicode")]
48 VariableUnicode {
49 variable: String,
51 },
52
53 #[error("configuration variable `{variable}` {message}")]
55 VariableValue {
56 variable: &'static str,
58 message: &'static str,
60 },
61
62 #[error("failed to read configuration value selected by `{variable}_FILE`")]
64 VariableFile {
65 variable: &'static str,
67 #[source]
69 source: io::Error,
70 },
71}
72
73#[derive(Debug, Error)]
75pub enum EnvironmentFileError {
76 #[error("environment file could not be read")]
78 Io(#[source] io::Error),
79 #[error("invalid dotenv syntax at character index {index}")]
81 Syntax {
82 index: usize,
84 },
85 #[error("referenced environment variable is unavailable")]
87 Variable,
88 #[error("environment file could not be loaded")]
90 Other,
91}
92
93impl EnvironmentFileError {
94 pub(crate) fn from_dotenv(error: dotenv::Error) -> Self {
95 match error {
96 dotenv::Error::Parse(error, _) => Self::Syntax {
97 index: error.column().saturating_sub(1),
98 },
99 dotenv::Error::Io(source, _) => Self::Io(source),
100 dotenv::Error::NotPresent(_)
101 | dotenv::Error::NotUnicode(_, _)
102 | dotenv::Error::NotUnicodeName(_) => Self::Variable,
103 _ => Self::Other,
104 }
105 }
106}
107
108impl ConfigError {
109 pub(crate) const fn validation(field: &'static str, message: &'static str) -> Self {
110 Self::Validation { field, message }
111 }
112
113 pub(crate) fn environment(path: PathBuf, error: dotenv::Error) -> Self {
114 Self::Environment {
115 path,
116 source: EnvironmentFileError::from_dotenv(error),
117 }
118 }
119}
120
121pub type Result<T> = std::result::Result<T, ConfigError>;