// file: crates/knowledge-git-lib/src/error.rs // version: 5 //! Recoverable errors for controlled Git process execution. /// Git operation category safe to expose in diagnostics. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum GitOperation { /// Clone one configured source into a controlled mirror. CloneMirror, /// Inspect whether a controlled repository is a valid bare mirror. InspectMirror, /// Refresh refs in one controlled mirror. RefreshMirror, /// Resolve one configured reference to a commit revision. ResolveRevision, /// Materialize one detached revision-addressed snapshot. CreateSnapshot, /// Validate an existing detached snapshot before reuse. InspectSnapshot, /// Create one isolated detached worktree for candidate construction. CreateWriteWorktree, /// Stage the requested candidate mutations. StageCandidate, /// Inspect the candidate index, commit or parent relationship. InspectCandidate, /// Create the candidate commit with explicit identity. CommitCandidate, /// Retain the detached candidate commit under an internal backend reference. PreserveCandidate, /// Remove one backend-owned candidate worktree. RemoveWriteWorktree, /// Observe the current state of one remote branch. InspectRemote, /// Push one candidate revision with an explicit compare-and-exchange guard. PushCandidate, } impl std::fmt::Display for crate::GitOperation { fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { crate::GitOperation::CloneMirror => return formatter.write_str("clone mirror"), crate::GitOperation::InspectMirror => return formatter.write_str("inspect mirror"), crate::GitOperation::RefreshMirror => return formatter.write_str("refresh mirror"), crate::GitOperation::ResolveRevision => return formatter.write_str("resolve revision"), crate::GitOperation::CreateSnapshot => return formatter.write_str("create snapshot"), crate::GitOperation::InspectSnapshot => return formatter.write_str("inspect snapshot"), crate::GitOperation::CreateWriteWorktree => return formatter.write_str("create write worktree"), crate::GitOperation::StageCandidate => return formatter.write_str("stage candidate"), crate::GitOperation::InspectCandidate => return formatter.write_str("inspect candidate"), crate::GitOperation::CommitCandidate => return formatter.write_str("commit candidate"), crate::GitOperation::PreserveCandidate => return formatter.write_str("preserve candidate"), crate::GitOperation::RemoveWriteWorktree => return formatter.write_str("remove write worktree"), crate::GitOperation::InspectRemote => return formatter.write_str("inspect remote branch"), crate::GitOperation::PushCandidate => return formatter.write_str("push guarded candidate"), } } } /// Recoverable error returned by the controlled Git backend. /// /// Process failures intentionally retain only an operation category and exit code. Source URLs, /// command arguments, stderr and credentials are not embedded in this public error. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum GitBackendError { /// The configured Git executable path is empty. EmptyGitExecutable, /// The configured state root is empty. EmptyStateRoot, /// A local source path or remote source string is empty. EmptySourceLocation, /// One logical source identifier was registered more than once in the same backend. DuplicateSource, /// No physical source configuration is registered for the requested logical source. SourceNotConfigured, /// The backend could not prepare its generated-state directories. StatePreparationFailed, /// The Git executable could not be started for the requested operation. GitUnavailable { /// Operation that could not start. operation: crate::GitOperation, }, /// Git returned a non-success status for the requested operation. GitCommandFailed { /// Operation that failed. operation: crate::GitOperation, /// Process exit code when the operating system exposed one. exit_code: Option, }, /// An existing controlled repository is not a valid bare mirror. InvalidMirror, /// A controlled mirror required by a read operation does not exist yet. MirrorMissing, /// A revision supplied to snapshot materialization is not a safe Git object identity. InvalidRevision, /// An existing snapshot does not match the requested revision or is not clean. InvalidSnapshot, /// The deterministic backend-owned write worktree path already exists unexpectedly. WriteWorktreeExists, /// A mutation would traverse or replace a symbolic link. UnsafeMutationTarget, /// A requested deletion target does not exist. MutationTargetMissing, /// A filesystem mutation or parent-directory preparation failed. MutationFilesystemFailed, /// The staged candidate paths do not exactly match the requested mutation set. CandidateMutationMismatch, /// The resulting candidate commit does not have the requested base as its sole first parent. InvalidCandidate, /// A backend-owned write worktree could not be removed deterministically. WriteCleanupFailed, /// Git returned output that does not satisfy the backend contract. UnexpectedGitOutput { /// Operation whose output could not be validated. operation: crate::GitOperation, }, } impl std::fmt::Display for crate::GitBackendError { fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { crate::GitBackendError::EmptyGitExecutable => return formatter.write_str("git executable must not be empty"), crate::GitBackendError::EmptyStateRoot => return formatter.write_str("git state root must not be empty"), crate::GitBackendError::EmptySourceLocation => return formatter.write_str("git source location must not be empty"), crate::GitBackendError::DuplicateSource => return formatter.write_str("git source identifier is already configured"), crate::GitBackendError::SourceNotConfigured => return formatter.write_str("git source identifier is not configured"), crate::GitBackendError::StatePreparationFailed => return formatter.write_str("git state directories could not be prepared"), crate::GitBackendError::GitUnavailable { operation } => return write!(formatter, "git is unavailable while attempting to {operation}"), crate::GitBackendError::GitCommandFailed { operation, exit_code } => { return write!(formatter, "git failed while attempting to {operation}; exit code {exit_code:?}"); }, crate::GitBackendError::InvalidMirror => return formatter.write_str("controlled git repository is not a valid bare mirror"), crate::GitBackendError::MirrorMissing => return formatter.write_str("controlled git mirror does not exist"), crate::GitBackendError::InvalidRevision => return formatter.write_str("git revision is not a safe object identity"), crate::GitBackendError::InvalidSnapshot => return formatter.write_str("controlled git snapshot is invalid or dirty"), crate::GitBackendError::WriteWorktreeExists => return formatter.write_str("controlled git write worktree already exists"), crate::GitBackendError::UnsafeMutationTarget => return formatter.write_str("git mutation target traverses a symbolic link"), crate::GitBackendError::MutationTargetMissing => return formatter.write_str("git deletion target does not exist"), crate::GitBackendError::MutationFilesystemFailed => return formatter.write_str("git candidate filesystem mutation failed"), crate::GitBackendError::CandidateMutationMismatch => return formatter.write_str("git candidate staged paths do not match requested mutations"), crate::GitBackendError::InvalidCandidate => return formatter.write_str("git candidate commit does not match the requested base"), crate::GitBackendError::WriteCleanupFailed => return formatter.write_str("controlled git write worktree cleanup failed"), crate::GitBackendError::UnexpectedGitOutput { operation } => { return write!(formatter, "git returned unexpected output while attempting to {operation}"); }, } } } impl std::error::Error for crate::GitBackendError {}