1use thiserror::Error;
4
5#[derive(Error, Debug)]
7pub enum IpcError {
8 #[error("Connection failed: {0}")]
10 ConnectionFailed(String),
11
12 #[error("Request timed out after {0}ms")]
14 Timeout(u64),
15
16 #[error("Serialization error: {0}")]
18 Serialization(String),
19
20 #[error("Deserialization error: {0}")]
22 Deserialization(String),
23
24 #[error("Protocol version mismatch: expected {expected}, got {actual}")]
26 VersionMismatch { expected: u32, actual: u32 },
27
28 #[error("Daemon not running")]
30 DaemonNotRunning,
31
32 #[error("Daemon error [{code}]: {message}")]
34 DaemonError { code: String, message: String },
35
36 #[error("Lock file error: {0}")]
38 LockFile(String),
39
40 #[error("Lock held by process {pid} (expires in {expires_in_ms}ms)")]
42 LockHeld { pid: u32, expires_in_ms: u64 },
43
44 #[error("Lock acquisition race lost: another process acquired the lock simultaneously")]
46 LockRace,
47
48 #[error("Lock expired")]
50 LockExpired,
51
52 #[error("Client connection is poisoned after a previous error; reconnect to continue")]
54 ClientPoisoned,
55
56 #[error("IO error: {0}")]
58 Io(#[from] std::io::Error),
59
60 #[error("JSON error: {0}")]
62 Json(#[from] serde_json::Error),
63}
64
65impl From<IpcError> for libgrite_core::GriteError {
67 fn from(e: IpcError) -> Self {
68 match e {
69 IpcError::DaemonNotRunning => {
70 libgrite_core::GriteError::Ipc("Daemon not running".to_string())
71 }
72 IpcError::Timeout(_) => libgrite_core::GriteError::Ipc("IPC timeout".to_string()),
73 IpcError::LockHeld { pid, expires_in_ms } => {
74 libgrite_core::GriteError::DbBusy(format!(
75 "Daemon lock held by process {} (expires in {}s)",
76 pid,
77 expires_in_ms / 1000
78 ))
79 }
80 IpcError::LockRace => libgrite_core::GriteError::Conflict(
81 "Another process acquired the daemon lock simultaneously".to_string(),
82 ),
83 IpcError::LockExpired => {
84 libgrite_core::GriteError::Ipc("Daemon lock expired".to_string())
85 }
86 other => libgrite_core::GriteError::Ipc(other.to_string()),
87 }
88 }
89}
90
91pub mod codes {
93 pub const DB_BUSY: &str = "db_busy";
94 pub const NOT_FOUND: &str = "not_found";
95 pub const INVALID_INPUT: &str = "invalid_input";
96 pub const INTERNAL: &str = "internal";
97 pub const NOT_INITIALIZED: &str = "not_initialized";
98 pub const IO_ERROR: &str = "io_error";
99 pub const GIT_ERROR: &str = "git_error";
100 pub const IPC_ERROR: &str = "ipc_error";
101}