code_digest/utils/
error.rs

1//! Error types for code-digest
2
3use thiserror::Error;
4
5/// Main error type for code-digest operations
6#[derive(Error, Debug)]
7pub enum CodeDigestError {
8    /// File system related errors
9    #[error("Invalid path: {0}")]
10    InvalidPath(String),
11
12    #[error("Failed to read file: {0}")]
13    ReadError(String),
14
15    #[error("Failed to write file: {0}")]
16    WriteError(String),
17
18    /// Configuration errors
19    #[error("Invalid configuration: {0}")]
20    InvalidConfiguration(String),
21
22    #[error("Failed to parse configuration: {0}")]
23    ConfigParseError(String),
24
25    #[error("Configuration file error: {0}")]
26    ConfigError(String),
27
28    /// Processing errors
29    #[error("Token counting error: {0}")]
30    TokenCountError(String),
31
32    #[error("Markdown generation error: {0}")]
33    MarkdownGenerationError(String),
34
35    #[error("File prioritization error: {0}")]
36    PrioritizationError(String),
37
38    /// External tool errors
39    #[error("{tool} not found. {install_instructions}")]
40    LlmToolNotFound { tool: String, install_instructions: String },
41
42    #[error("Subprocess error: {0}")]
43    SubprocessError(String),
44
45    /// Resource limits
46    #[error("File too large: {0} (max: {1} bytes)")]
47    FileTooLarge(String, usize),
48
49    #[error("Token limit exceeded: {current} tokens (max: {max})")]
50    TokenLimitExceeded { current: usize, max: usize },
51
52    /// Pattern matching errors
53    #[error("Invalid glob pattern: {0}")]
54    InvalidGlobPattern(String),
55
56    /// Remote repository errors
57    #[error("Remote fetch error: {0}")]
58    RemoteFetchError(String),
59
60    /// Clipboard errors
61    #[error("Clipboard error: {0}")]
62    ClipboardError(String),
63
64    /// Parallel processing errors
65    #[error("File processing error for {path}: {error}")]
66    FileProcessingError { path: String, error: String },
67
68    #[error("Token counting error for {path}: {error}")]
69    TokenCountingError { path: String, error: String },
70
71    #[error("Parallel processing errors: {error_count} files failed")]
72    ParallelProcessingErrors { error_count: usize },
73
74    /// General I/O errors
75    #[error("I/O error: {0}")]
76    IoError(#[from] std::io::Error),
77
78    /// UTF-8 conversion errors
79    #[error("UTF-8 conversion error: {0}")]
80    Utf8Error(#[from] std::string::FromUtf8Error),
81}
82
83/// Result type alias for code-digest operations
84pub type Result<T> = std::result::Result<T, CodeDigestError>;
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89
90    #[test]
91    fn test_error_display() {
92        let err = CodeDigestError::InvalidPath("/invalid/path".to_string());
93        assert_eq!(err.to_string(), "Invalid path: /invalid/path");
94
95        let err = CodeDigestError::TokenLimitExceeded { current: 200000, max: 150000 };
96        assert_eq!(err.to_string(), "Token limit exceeded: 200000 tokens (max: 150000)");
97    }
98
99    #[test]
100    fn test_io_error_conversion() {
101        let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
102        let err: CodeDigestError = io_err.into();
103        assert!(matches!(err, CodeDigestError::IoError(_)));
104    }
105}