llm_coding_tools_core/
error.rs

1//! Common error types for coding tools.
2
3use thiserror::Error;
4
5/// Unified error type for all tool operations.
6#[derive(Debug, Error)]
7pub enum ToolError {
8    /// File I/O operation failed.
9    #[error("I/O error: {0}")]
10    Io(#[from] std::io::Error),
11
12    /// Path validation failed (not absolute, doesn't exist, etc.).
13    #[error("invalid path: {0}")]
14    InvalidPath(String),
15
16    /// Requested offset/limit exceeds file bounds.
17    #[error("out of bounds: {0}")]
18    OutOfBounds(String),
19
20    /// Glob/regex pattern is invalid.
21    #[error("invalid pattern: {0}")]
22    InvalidPattern(String),
23
24    /// HTTP request failed.
25    #[error("HTTP error: {0}")]
26    Http(String),
27
28    /// Command execution failed.
29    #[error("execution error: {0}")]
30    Execution(String),
31
32    /// Timeout exceeded.
33    #[error("timeout: {0}")]
34    Timeout(String),
35
36    /// Validation failed.
37    #[error("validation error: {0}")]
38    Validation(String),
39
40    /// JSON serialization/deserialization failed.
41    #[error("JSON error: {0}")]
42    Json(#[from] serde_json::Error),
43}
44
45/// Result type alias for tool operations.
46pub type ToolResult<T> = Result<T, ToolError>;
47
48impl From<globset::Error> for ToolError {
49    fn from(e: globset::Error) -> Self {
50        ToolError::InvalidPattern(e.to_string())
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn tool_error_displays_io_error() {
60        let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
61        let err: ToolError = io_err.into();
62        assert!(err.to_string().contains("I/O error"));
63    }
64
65    #[test]
66    fn tool_error_displays_invalid_path() {
67        let err = ToolError::InvalidPath("not absolute".into());
68        assert!(err.to_string().contains("invalid path"));
69    }
70
71    #[test]
72    fn tool_error_from_glob_pattern_error() {
73        let glob_err = globset::Glob::new("[invalid").unwrap_err();
74        let err: ToolError = glob_err.into();
75        assert!(matches!(err, ToolError::InvalidPattern(_)));
76    }
77}