Skip to main content

codesearch/
error.rs

1//! Centralized error types for codesearch
2//!
3//! This module provides a unified error handling approach using thiserror,
4//! replacing the ad-hoc anyhow::Error usage throughout the codebase.
5
6use std::path::PathBuf;
7use thiserror::Error;
8
9/// Main error type for codesearch operations
10#[derive(Error, Debug)]
11pub enum CodeSearchError {
12    /// Database-related errors
13    #[error("Database error: {message}")]
14    Database {
15        message: String,
16        source: Option<anyhow::Error>,
17    },
18
19    /// I/O operation errors
20    #[error("I/O error: {path} - {message}")]
21    Io {
22        path: PathBuf,
23        message: String,
24        source: Option<anyhow::Error>,
25    },
26
27    /// Embedding model errors
28    #[error("Embedding error: {message}")]
29    Embedding { message: String },
30
31    /// Search operation errors
32    #[error("Search error: {message}")]
33    Search { message: String },
34
35    /// Index operation errors
36    #[error("Index error: {message}")]
37    Index { message: String },
38
39    /// Configuration errors
40    #[error("Configuration error: {message}")]
41    Config { message: String },
42
43    /// MCP server errors
44    #[error("MCP error: {message}")]
45    Mcp { message: String },
46
47    /// File parsing errors
48    #[error("Parse error: {path} - {message}")]
49    Parse {
50        path: PathBuf,
51        message: String,
52        source: Option<anyhow::Error>,
53    },
54
55    /// Validation errors
56    #[error("Validation error: {message}")]
57    Validation { message: String },
58}
59
60impl CodeSearchError {
61    /// Create a database error
62    pub fn database(message: impl Into<String>) -> Self {
63        Self::Database {
64            message: message.into(),
65            source: None,
66        }
67    }
68
69    /// Create an I/O error
70    pub fn io(path: impl Into<PathBuf>, message: impl Into<String>) -> Self {
71        Self::Io {
72            path: path.into(),
73            message: message.into(),
74            source: None,
75        }
76    }
77
78    /// Create an embedding error
79    pub fn embedding(message: impl Into<String>) -> Self {
80        Self::Embedding {
81            message: message.into(),
82        }
83    }
84
85    /// Create a search error
86    pub fn search(message: impl Into<String>) -> Self {
87        Self::Search {
88            message: message.into(),
89        }
90    }
91
92    /// Create an index error
93    pub fn index(message: impl Into<String>) -> Self {
94        Self::Index {
95            message: message.into(),
96        }
97    }
98
99    /// Create a configuration error
100    pub fn config(message: impl Into<String>) -> Self {
101        Self::Config {
102            message: message.into(),
103        }
104    }
105
106    /// Create an MCP error
107    pub fn mcp(message: impl Into<String>) -> Self {
108        Self::Mcp {
109            message: message.into(),
110        }
111    }
112
113    /// Create a parse error
114    pub fn parse(path: impl Into<PathBuf>, message: impl Into<String>) -> Self {
115        Self::Parse {
116            path: path.into(),
117            message: message.into(),
118            source: None,
119        }
120    }
121
122    /// Create a validation error
123    pub fn validation(message: impl Into<String>) -> Self {
124        Self::Validation {
125            message: message.into(),
126        }
127    }
128}
129
130/// Result type alias for codesearch operations
131pub type Result<T> = std::result::Result<T, CodeSearchError>;
132
133// Conversion from std::io::Error
134impl From<std::io::Error> for CodeSearchError {
135    fn from(err: std::io::Error) -> Self {
136        Self::Io {
137            path: PathBuf::new(),
138            message: err.to_string(),
139            source: None,
140        }
141    }
142}
143
144// Conversion from anyhow::Error (for gradual migration)
145impl From<anyhow::Error> for CodeSearchError {
146    fn from(err: anyhow::Error) -> Self {
147        Self::Database {
148            message: err.to_string(),
149            source: Some(err),
150        }
151    }
152}
153
154#[cfg(test)]
155mod tests {
156    use super::*;
157
158    #[test]
159    fn test_error_creation() {
160        let err = CodeSearchError::database("Test error");
161        assert!(err.to_string().contains("Database error"));
162
163        let err = CodeSearchError::validation("Invalid input");
164        assert!(err.to_string().contains("Validation error"));
165    }
166
167    #[test]
168    fn test_io_error() {
169        let path = PathBuf::from("/test/path");
170        let err = CodeSearchError::io(&path, "File not found");
171        assert!(err.to_string().contains("I/O error"));
172        assert!(err.to_string().contains("/test/path"));
173    }
174}