Skip to main content

khive_vcs/
error.rs

1// Copyright 2026 khive contributors. Licensed under Apache-2.0.
2//
3//! Error types for the VCS layer.
4//!
5//! Remote-server and custom-push/pull error variants (`RemoteUnreachable`,
6//! `AuthFailed`, `NonFastForward`, `MergeRequired`) were removed per ADR-010/
7//! ADR-020: git is the remote protocol; there is no custom `khive-sync` server.
8//! `MergeNotImplemented` was removed because the custom merge engine is
9//! superseded for v1 (ADR-020 §what-adr-010-retains-this-adr-replaces).
10
11use thiserror::Error;
12
13use crate::types::SnapshotId;
14
15#[derive(Debug, Error)]
16pub enum VcsError {
17    /// The archive stored at the remote has a different hash than expected.
18    /// Indicates corruption or tampering.
19    #[error("hash mismatch: expected {expected}, actual {actual}")]
20    HashMismatch {
21        expected: SnapshotId,
22        actual: SnapshotId,
23    },
24
25    /// `checkout` was blocked because there are uncommitted changes.
26    /// Pass `force: true` to discard them.
27    #[error("uncommitted changes: {count} entities/edges modified since last commit")]
28    UncommittedChanges { count: usize },
29
30    /// A `SnapshotId` string failed validation.
31    #[error("invalid snapshot id: {0}")]
32    InvalidSnapshotId(String),
33
34    /// A branch name failed validation (must match `^[a-zA-Z0-9_-]{1,64}$`).
35    #[error("invalid branch name: {0:?}")]
36    InvalidBranchName(String),
37
38    /// An underlying storage operation failed.
39    #[error("storage: {0}")]
40    Storage(String),
41
42    /// JSON serialization or deserialization failed.
43    #[error("json: {0}")]
44    Json(#[from] serde_json::Error),
45
46    /// An I/O operation failed (file system).
47    #[error("io: {0}")]
48    Io(#[from] std::io::Error),
49
50    /// An unexpected internal error.
51    #[error("internal: {0}")]
52    Internal(String),
53}
54
55impl From<khive_runtime::error::RuntimeError> for VcsError {
56    fn from(e: khive_runtime::error::RuntimeError) -> Self {
57        VcsError::Storage(e.to_string())
58    }
59}