Skip to main content

aivcs_core/multi_repo/
error.rs

1//! Error types for multi-repo and CI/CD orchestration.
2
3use thiserror::Error;
4
5/// Errors produced by the multi-repo orchestration layer.
6#[derive(Debug, Error)]
7pub enum MultiRepoError {
8    /// A dependency cycle was detected in the repo graph.
9    #[error("dependency cycle detected involving repos: {repos:?}")]
10    DependencyCycle { repos: Vec<String> },
11
12    /// A referenced repo was not found in the graph.
13    #[error("repo not found in graph: {repo}")]
14    RepoNotFound { repo: String },
15
16    /// Release sequencing failed for a repo.
17    #[error("release sequencing failed for repo {repo}: {reason}")]
18    SequencingFailed { repo: String, reason: String },
19
20    /// CI aggregation failed for an objective.
21    #[error("CI aggregation error for objective '{objective}': {detail}")]
22    AggregationError { objective: String, detail: String },
23
24    /// A backport operation failed.
25    #[error("backport failed for commit {commit_sha} → branch {target_branch}: {reason}")]
26    BackportFailed {
27        commit_sha: String,
28        target_branch: String,
29        reason: String,
30    },
31
32    /// A provenance artifact operation failed.
33    #[error("provenance artifact error: {0}")]
34    Provenance(String),
35
36    /// A storage / persistence layer error.
37    #[error("storage error: {0}")]
38    Storage(String),
39
40    /// Bubbled-up domain error.
41    #[error("domain error: {0}")]
42    Domain(#[from] crate::domain::error::AivcsError),
43}
44
45/// Convenience result alias.
46pub type MultiRepoResult<T> = std::result::Result<T, MultiRepoError>;
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn test_dependency_cycle_error_displays_repo_names() {
54        let err = MultiRepoError::DependencyCycle {
55            repos: vec!["org/a".to_string(), "org/b".to_string()],
56        };
57        let msg = err.to_string();
58        assert!(msg.contains("org/a"));
59        assert!(msg.contains("org/b"));
60    }
61
62    #[test]
63    fn test_backport_failed_error_displays_commit_and_branch() {
64        let err = MultiRepoError::BackportFailed {
65            commit_sha: "abc123".to_string(),
66            target_branch: "release/1.0".to_string(),
67            reason: "conflict in foo.rs".to_string(),
68        };
69        let msg = err.to_string();
70        assert!(msg.contains("abc123"));
71        assert!(msg.contains("release/1.0"));
72        assert!(msg.contains("conflict"));
73    }
74
75    #[test]
76    fn test_repo_not_found_error_displays_repo() {
77        let err = MultiRepoError::RepoNotFound {
78            repo: "org/missing".to_string(),
79        };
80        assert!(err.to_string().contains("org/missing"));
81    }
82}