use thiserror::Error;
#[derive(Debug, Error)]
pub enum MultiRepoError {
#[error("dependency cycle detected involving repos: {repos:?}")]
DependencyCycle { repos: Vec<String> },
#[error("repo not found in graph: {repo}")]
RepoNotFound { repo: String },
#[error("release sequencing failed for repo {repo}: {reason}")]
SequencingFailed { repo: String, reason: String },
#[error("CI aggregation error for objective '{objective}': {detail}")]
AggregationError { objective: String, detail: String },
#[error("backport failed for commit {commit_sha} → branch {target_branch}: {reason}")]
BackportFailed {
commit_sha: String,
target_branch: String,
reason: String,
},
#[error("provenance artifact error: {0}")]
Provenance(String),
#[error("storage error: {0}")]
Storage(String),
#[error("domain error: {0}")]
Domain(#[from] crate::domain::error::AivcsError),
}
pub type MultiRepoResult<T> = std::result::Result<T, MultiRepoError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dependency_cycle_error_displays_repo_names() {
let err = MultiRepoError::DependencyCycle {
repos: vec!["org/a".to_string(), "org/b".to_string()],
};
let msg = err.to_string();
assert!(msg.contains("org/a"));
assert!(msg.contains("org/b"));
}
#[test]
fn test_backport_failed_error_displays_commit_and_branch() {
let err = MultiRepoError::BackportFailed {
commit_sha: "abc123".to_string(),
target_branch: "release/1.0".to_string(),
reason: "conflict in foo.rs".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("abc123"));
assert!(msg.contains("release/1.0"));
assert!(msg.contains("conflict"));
}
#[test]
fn test_repo_not_found_error_displays_repo() {
let err = MultiRepoError::RepoNotFound {
repo: "org/missing".to_string(),
};
assert!(err.to_string().contains("org/missing"));
}
}