use thiserror::Error;
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum BuildError {
#[error("primitive `{needed_by}` requires `{missing}` to be configured")]
MissingDependency {
needed_by: String,
missing: String,
},
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum OpsError {
#[error("denied: {code}")]
Denied {
code: String,
reason: Option<String>,
},
#[error("require approval")]
RequireApproval,
#[error("timed out at phase `{phase}`")]
TimedOut {
phase: String,
},
#[error("saturated: {scope}")]
Saturated {
scope: String,
},
#[error("halted")]
Halted,
#[error("unavailable: {component}")]
Unavailable {
component: String,
},
#[error("integrity failed: {reasons}")]
IntegrityFailed {
reasons: String,
},
#[error(transparent)]
Build(#[from] BuildError),
#[error("internal: {source}")]
Internal {
source: Box<dyn std::error::Error + Send + Sync>,
},
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn build_error_displays_missing_dependency() {
let e = BuildError::MissingDependency {
needed_by: "gates".into(),
missing: "escalation".into(),
};
let s = format!("{e}");
assert!(s.contains("gates"));
assert!(s.contains("escalation"));
}
#[test]
fn ops_error_halted_is_distinct_from_unavailable() {
let a = OpsError::Halted;
let b = OpsError::Unavailable {
component: "kv".into(),
};
assert_ne!(format!("{a}"), format!("{b}"));
}
}