codex_memory/
error.rs

1use std::fmt;
2
3/// Enhanced error type with comprehensive error handling
4#[derive(Debug)]
5pub enum Error {
6    Database(sqlx::Error),
7    Config(String),
8    Io(std::io::Error),
9    Json(serde_json::Error),
10    Other(String),
11    // MCP-specific errors for JSON-RPC 2.0 compliance
12    ParseError(String),      // -32700
13    InvalidRequest(String),  // -32600
14    MethodNotFound(String),  // -32601
15    InvalidParams(String),   // -32602
16    InternalError(String),   // -32603
17    Timeout(String),         // -32603 with timeout details
18    // Enhanced error types for better error handling
19    ValidationError(String), // Input validation failures
20    NotFound(String),       // Resource not found errors
21    Conflict(String),       // Conflict errors (duplicates, etc.)
22    Unauthorized(String),   // Authorization errors
23    RateLimited(String),    // Rate limiting errors
24}
25
26impl fmt::Display for Error {
27    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28        match self {
29            Error::Database(e) => write!(f, "Database error: {}", e),
30            Error::Config(e) => write!(f, "Configuration error: {}", e),
31            Error::Io(e) => write!(f, "IO error: {}", e),
32            Error::Json(e) => write!(f, "JSON error: {}", e),
33            Error::Other(e) => write!(f, "Error: {}", e),
34            Error::ParseError(e) => write!(f, "Parse error: {}", e),
35            Error::InvalidRequest(e) => write!(f, "Invalid request: {}", e),
36            Error::MethodNotFound(e) => write!(f, "Method not found: {}", e),
37            Error::InvalidParams(e) => write!(f, "Invalid params: {}", e),
38            Error::InternalError(e) => write!(f, "Internal error: {}", e),
39            Error::Timeout(e) => write!(f, "Timeout: {}", e),
40            Error::ValidationError(e) => write!(f, "Validation error: {}", e),
41            Error::NotFound(e) => write!(f, "Not found: {}", e),
42            Error::Conflict(e) => write!(f, "Conflict: {}", e),
43            Error::Unauthorized(e) => write!(f, "Unauthorized: {}", e),
44            Error::RateLimited(e) => write!(f, "Rate limited: {}", e),
45        }
46    }
47}
48
49impl std::error::Error for Error {}
50
51impl From<sqlx::Error> for Error {
52    fn from(e: sqlx::Error) -> Self {
53        Error::Database(e)
54    }
55}
56
57impl From<std::io::Error> for Error {
58    fn from(e: std::io::Error) -> Self {
59        Error::Io(e)
60    }
61}
62
63impl From<serde_json::Error> for Error {
64    fn from(e: serde_json::Error) -> Self {
65        Error::Json(e)
66    }
67}
68
69impl From<anyhow::Error> for Error {
70    fn from(e: anyhow::Error) -> Self {
71        Error::Other(e.to_string())
72    }
73}
74
75impl From<url::ParseError> for Error {
76    fn from(e: url::ParseError) -> Self {
77        Error::Config(format!("Invalid URL: {}", e))
78    }
79}
80
81impl From<uuid::Error> for Error {
82    fn from(e: uuid::Error) -> Self {
83        Error::InvalidParams(format!("Invalid UUID: {}", e))
84    }
85}
86
87impl From<regex::Error> for Error {
88    fn from(e: regex::Error) -> Self {
89        Error::InternalError(format!("Regex error: {}", e))
90    }
91}
92
93impl From<tokio::time::error::Elapsed> for Error {
94    fn from(_: tokio::time::error::Elapsed) -> Self {
95        Error::Timeout("Operation timed out".to_string())
96    }
97}
98
99impl Error {
100    /// Get the appropriate JSON-RPC 2.0 error code for this error
101    pub fn json_rpc_code(&self) -> i32 {
102        match self {
103            Error::ParseError(_) => -32700,        // Parse error
104            Error::InvalidRequest(_) => -32600,    // Invalid Request
105            Error::MethodNotFound(_) => -32601,    // Method not found
106            Error::InvalidParams(_) | Error::ValidationError(_) => -32602, // Invalid params
107            Error::InternalError(_) | Error::Timeout(_) => -32603, // Internal error
108            Error::Database(_) => -32603,          // Internal error (database)
109            Error::Config(_) => -32603,            // Internal error (config)
110            Error::Io(_) => -32603,                // Internal error (I/O)
111            Error::Json(_) => -32700,              // Parse error (JSON)
112            Error::Other(_) => -32603,             // Internal error (generic)
113            Error::NotFound(_) => -32001,          // Custom: Resource not found
114            Error::Conflict(_) => -32002,          // Custom: Resource conflict
115            Error::Unauthorized(_) => -32003,     // Custom: Unauthorized access
116            Error::RateLimited(_) => -32004,       // Custom: Rate limit exceeded
117        }
118    }
119
120    /// Create a JSON-RPC 2.0 compliant error response
121    pub fn to_json_rpc_error(&self, id: Option<serde_json::Value>) -> serde_json::Value {
122        serde_json::json!({
123            "jsonrpc": "2.0",
124            "id": id,
125            "error": {
126                "code": self.json_rpc_code(),
127                "message": self.to_string()
128            }
129        })
130    }
131}
132
133pub type Result<T> = std::result::Result<T, Error>;