Skip to main content

juncture_checkpoint/
error.rs

1//! Checkpoint error types
2
3use std::io;
4
5/// Checkpoint operation errors
6///
7/// Represents all possible errors that can occur during checkpoint operations,
8/// including serialization, storage, and schema migration failures.
9#[derive(Debug, thiserror::Error)]
10pub enum CheckpointError {
11    /// Serialization failed
12    ///
13    /// Occurs when converting checkpoint data to a serialized format (JSON/MessagePack).
14    #[error("Serialization failed: {0}")]
15    Serialize(#[source] Box<dyn std::error::Error + Send + Sync>),
16
17    /// Deserialization failed
18    ///
19    /// Occurs when parsing serialized data back into checkpoint structures.
20    #[error("Deserialization failed: {0}")]
21    Deserialize(#[source] Box<dyn std::error::Error + Send + Sync>),
22
23    /// Schema migration failed
24    ///
25    /// Occurs when migrating checkpoint data between incompatible schema versions.
26    #[error("Schema migration failed: from version {from} to {to}: {reason}")]
27    SchemaMigration {
28        /// Source schema version
29        from: u32,
30        /// Target schema version
31        to: u32,
32        /// Human-readable reason for migration failure
33        reason: String,
34    },
35
36    /// Storage operation error
37    ///
38    /// Occurs when underlying storage backend fails (database, filesystem, etc.).
39    #[error("Storage error: {0}")]
40    Storage(#[source] Box<dyn std::error::Error + Send + Sync>),
41
42    /// Database operation error
43    ///
44    /// Occurs when database operations fail (query, connection, transaction, etc.).
45    #[error("Database error: {0}")]
46    Database(#[source] Box<dyn std::error::Error + Send + Sync>),
47
48    /// Serialization error (alias for Serialize)
49    ///
50    /// This variant is an alias for `Serialize` and exists for compatibility
51    /// with external code that expects this name.
52    #[error("Serialization error: {0}")]
53    Serialization(#[source] Box<dyn std::error::Error + Send + Sync>),
54
55    /// Checkpoint not found
56    ///
57    /// Occurs when attempting to retrieve a non-existent checkpoint.
58    #[error("Checkpoint not found: thread={thread_id}, id={checkpoint_id}")]
59    NotFound {
60        /// Thread identifier
61        thread_id: String,
62        /// Checkpoint identifier
63        checkpoint_id: String,
64    },
65
66    /// Connection pool exhausted
67    ///
68    /// Occurs when no database connections are available in the pool.
69    #[error("Connection pool exhausted")]
70    PoolExhausted,
71}
72
73impl From<serde_json::Error> for CheckpointError {
74    fn from(err: serde_json::Error) -> Self {
75        Self::Serialize(Box::new(err))
76    }
77}
78
79impl From<io::Error> for CheckpointError {
80    fn from(err: io::Error) -> Self {
81        Self::Storage(Box::new(err))
82    }
83}
84
85impl CheckpointError {
86    /// Create a serialization error from a string message
87    #[must_use]
88    pub fn serialize_msg(msg: String) -> Self {
89        Self::Serialize(Box::new(StringError(msg)))
90    }
91
92    /// Create a deserialization error from a string message
93    #[must_use]
94    pub fn deserialize_msg(msg: String) -> Self {
95        Self::Deserialize(Box::new(StringError(msg)))
96    }
97
98    /// Create a storage error from a string message
99    #[must_use]
100    pub fn storage_msg(msg: String) -> Self {
101        Self::Storage(Box::new(StringError(msg)))
102    }
103
104    /// Create a database error from a string message
105    #[must_use]
106    pub fn database_msg(msg: String) -> Self {
107        Self::Database(Box::new(StringError(msg)))
108    }
109}
110
111/// Wrapper for String errors to convert them into Box<dyn Error>
112struct StringError(String);
113
114impl std::fmt::Debug for StringError {
115    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116        write!(f, "{}", self.0)
117    }
118}
119
120impl std::fmt::Display for StringError {
121    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122        write!(f, "{}", self.0)
123    }
124}
125
126impl std::error::Error for StringError {}
127
128// Rust guideline compliant 2026-05-24