use std::fmt;
#[derive(Debug)]
pub enum SecretResolutionError {
ConnectionFailed { address: String, source: String },
AuthenticationFailed { address: String, detail: String },
PathNotFound { path: String },
KeyNotFound { path: String, key: String },
NotFound { section: String, field: String },
InvalidFormat {
section: String,
field: String,
reason: String,
},
VaultError {
path: String,
status: u16,
body: String,
},
Multiple(Vec<SecretResolutionError>),
SecretIdEnvMissing { env_var: String },
}
impl fmt::Display for SecretResolutionError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::ConnectionFailed { address, source } => {
write!(f, "Vault connection failed to {address}: {source}")
}
Self::AuthenticationFailed { address, detail } => {
write!(f, "Vault authentication failed at {address}: {detail}")
}
Self::PathNotFound { path } => {
write!(f, "Vault path not found: {path}")
}
Self::KeyNotFound { path, key } => {
write!(f, "Vault key '{key}' not found at path {path}")
}
Self::NotFound { section, field } => {
write!(
f,
"Secret {section}.{field} not found: env var LATTICE_{}_{} not set and config value is empty",
section.to_uppercase(),
field.to_uppercase()
)
}
Self::InvalidFormat {
section,
field,
reason,
} => {
write!(f, "Secret {section}.{field} has invalid format: {reason}")
}
Self::VaultError { path, status, body } => {
write!(
f,
"Vault error at {path}: HTTP {status}: {}",
&body[..body.len().min(256)]
)
}
Self::Multiple(errors) => {
writeln!(f, "Multiple secret resolution errors:")?;
for (i, e) in errors.iter().enumerate() {
writeln!(f, " {}: {e}", i + 1)?;
}
Ok(())
}
Self::SecretIdEnvMissing { env_var } => {
write!(f, "Vault secret_id env var '{env_var}' is not set")
}
}
}
}
impl std::error::Error for SecretResolutionError {}