Skip to main content

rez_lsp_server/core/
error.rs

1//! Error types for the Rez LSP server.
2
3use std::fmt;
4
5/// Result type alias for the Rez LSP server.
6pub type Result<T> = std::result::Result<T, Error>;
7
8/// Main error type for the Rez LSP server.
9///
10/// This enum represents all possible errors that can occur in the LSP server.
11/// Each variant contains specific error information and context to help with
12/// debugging and error reporting.
13///
14/// # Error Categories
15///
16/// - **Config**: Configuration and environment setup errors
17/// - **Discovery**: Package discovery and scanning errors
18/// - **Parser**: Package file parsing errors
19/// - **Resolver**: Dependency resolution errors
20/// - **Lsp**: LSP protocol and communication errors
21/// - **Io**: File system and I/O errors
22/// - **Other**: Miscellaneous errors
23#[derive(Debug)]
24pub enum Error {
25    /// Configuration related errors
26    Config(ConfigError),
27    /// Package discovery related errors
28    Discovery(DiscoveryError),
29    /// Package parsing related errors
30    Parser(ParserError),
31    /// Dependency resolution related errors
32    Resolver(ResolverError),
33    /// LSP protocol related errors
34    Lsp(LspError),
35    /// Invalid file path
36    InvalidPath(String),
37    /// I/O related errors
38    Io(std::io::Error),
39    /// Other errors
40    Other(String),
41}
42
43/// Configuration error types
44#[derive(Debug)]
45pub enum ConfigError {
46    /// Environment variable not found
47    EnvVarNotFound(String),
48    /// Invalid path
49    InvalidPath(String),
50    /// No valid package paths found
51    NoValidPaths,
52    /// Configuration validation failed
53    ValidationFailed(String),
54}
55
56/// Package discovery error types
57#[derive(Debug)]
58pub enum DiscoveryError {
59    /// Failed to scan directory
60    ScanFailed(String),
61    /// Package not found
62    PackageNotFound(String),
63    /// Invalid package structure
64    InvalidStructure(String),
65    /// Cache operation failed
66    CacheFailed(String),
67}
68
69/// Parser error types
70#[derive(Debug)]
71pub enum ParserError {
72    /// Failed to read file
73    ReadFailed(String),
74    /// Invalid syntax
75    InvalidSyntax(String),
76    /// Missing required field
77    MissingField(String),
78    /// Invalid field value
79    InvalidValue(String),
80}
81
82/// Resolver error types
83#[derive(Debug)]
84pub enum ResolverError {
85    /// Dependency conflict
86    Conflict(String),
87    /// Circular dependency
88    CircularDependency(String),
89    /// Version constraint not satisfiable
90    UnsatisfiableConstraint(String),
91    /// Package not found during resolution
92    PackageNotFound(String),
93}
94
95/// LSP error types
96#[derive(Debug)]
97pub enum LspError {
98    /// Invalid request
99    InvalidRequest(String),
100    /// Server not initialized
101    NotInitialized,
102    /// Internal server error
103    Internal(String),
104}
105
106impl fmt::Display for Error {
107    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108        match self {
109            Error::Config(e) => write!(f, "Configuration error: {}", e),
110            Error::Discovery(e) => write!(f, "Discovery error: {}", e),
111            Error::Parser(e) => write!(f, "Parser error: {}", e),
112            Error::Resolver(e) => write!(f, "Resolver error: {}", e),
113            Error::Lsp(e) => write!(f, "LSP error: {}", e),
114            Error::InvalidPath(path) => write!(f, "Invalid path: {}", path),
115            Error::Io(e) => write!(f, "I/O error: {}", e),
116            Error::Other(msg) => write!(f, "Error: {}", msg),
117        }
118    }
119}
120
121impl fmt::Display for ConfigError {
122    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123        match self {
124            ConfigError::EnvVarNotFound(var) => {
125                write!(f, "Environment variable not found: {}", var)
126            }
127            ConfigError::InvalidPath(path) => write!(f, "Invalid path: {}", path),
128            ConfigError::NoValidPaths => write!(f, "No valid package paths found"),
129            ConfigError::ValidationFailed(msg) => write!(f, "Validation failed: {}", msg),
130        }
131    }
132}
133
134impl fmt::Display for DiscoveryError {
135    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136        match self {
137            DiscoveryError::ScanFailed(path) => write!(f, "Failed to scan directory: {}", path),
138            DiscoveryError::PackageNotFound(name) => write!(f, "Package not found: {}", name),
139            DiscoveryError::InvalidStructure(msg) => {
140                write!(f, "Invalid package structure: {}", msg)
141            }
142            DiscoveryError::CacheFailed(msg) => write!(f, "Cache operation failed: {}", msg),
143        }
144    }
145}
146
147impl fmt::Display for ParserError {
148    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149        match self {
150            ParserError::ReadFailed(path) => write!(f, "Failed to read file: {}", path),
151            ParserError::InvalidSyntax(msg) => write!(f, "Invalid syntax: {}", msg),
152            ParserError::MissingField(field) => write!(f, "Missing required field: {}", field),
153            ParserError::InvalidValue(msg) => write!(f, "Invalid field value: {}", msg),
154        }
155    }
156}
157
158impl fmt::Display for ResolverError {
159    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160        match self {
161            ResolverError::Conflict(msg) => write!(f, "Dependency conflict: {}", msg),
162            ResolverError::CircularDependency(msg) => write!(f, "Circular dependency: {}", msg),
163            ResolverError::UnsatisfiableConstraint(msg) => {
164                write!(f, "Unsatisfiable constraint: {}", msg)
165            }
166            ResolverError::PackageNotFound(name) => {
167                write!(f, "Package not found during resolution: {}", name)
168            }
169        }
170    }
171}
172
173impl fmt::Display for LspError {
174    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175        match self {
176            LspError::InvalidRequest(msg) => write!(f, "Invalid request: {}", msg),
177            LspError::NotInitialized => write!(f, "Server not initialized"),
178            LspError::Internal(msg) => write!(f, "Internal server error: {}", msg),
179        }
180    }
181}
182
183impl std::error::Error for Error {}
184impl std::error::Error for ConfigError {}
185impl std::error::Error for DiscoveryError {}
186impl std::error::Error for ParserError {}
187impl std::error::Error for ResolverError {}
188impl std::error::Error for LspError {}
189
190// Conversion implementations
191impl From<std::io::Error> for Error {
192    fn from(err: std::io::Error) -> Self {
193        Error::Io(err)
194    }
195}
196
197impl From<ConfigError> for Error {
198    fn from(err: ConfigError) -> Self {
199        Error::Config(err)
200    }
201}
202
203impl From<DiscoveryError> for Error {
204    fn from(err: DiscoveryError) -> Self {
205        Error::Discovery(err)
206    }
207}
208
209impl From<ParserError> for Error {
210    fn from(err: ParserError) -> Self {
211        Error::Parser(err)
212    }
213}
214
215impl From<ResolverError> for Error {
216    fn from(err: ResolverError) -> Self {
217        Error::Resolver(err)
218    }
219}
220
221impl From<LspError> for Error {
222    fn from(err: LspError) -> Self {
223        Error::Lsp(err)
224    }
225}
226
227impl From<regex::Error> for Error {
228    fn from(err: regex::Error) -> Self {
229        Error::Parser(ParserError::InvalidSyntax(err.to_string()))
230    }
231}