Skip to main content

khive_vcs/
error.rs

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