agentic_jujutsu/
error.rs

1//! Error types for agentic-jujutsu
2
3use thiserror::Error;
4
5/// Result type alias for agentic-jujutsu operations
6pub type Result<T> = std::result::Result<T, JJError>;
7
8/// Error types for Jujutsu operations
9#[derive(Error, Debug, Clone, PartialEq)]
10pub enum JJError {
11    /// jj command not found or not installed
12    #[error("jj command not found. Please install Jujutsu: https://github.com/jj-vcs/jj")]
13    JJNotFound,
14
15    /// jj command execution failed
16    #[error("jj command failed: {0}")]
17    CommandFailed(String),
18
19    /// Failed to parse jj output
20    #[error("Failed to parse jj output: {0}")]
21    ParseError(String),
22
23    /// Operation not found in log
24    #[error("Operation {0} not found")]
25    OperationNotFound(String),
26
27    /// Conflict resolution failed
28    #[error("Conflict resolution failed: {0}")]
29    ConflictResolutionFailed(String),
30
31    /// Invalid configuration
32    #[error("Invalid configuration: {0}")]
33    InvalidConfig(String),
34
35    /// I/O error
36    #[error("I/O error: {0}")]
37    IoError(String),
38
39    /// Serialization error
40    #[error("Serialization error: {0}")]
41    SerializationError(String),
42
43    /// Unknown error
44    #[error("Unknown error: {0}")]
45    Unknown(String),
46
47    /// MCP protocol error
48    #[error("MCP error: {0}")]
49    MCPError(String),
50}
51
52impl JJError {
53    /// Get error message as string
54    pub fn message(&self) -> String {
55        self.to_string()
56    }
57
58    /// Check if error is recoverable
59    pub fn is_recoverable(&self) -> bool {
60        matches!(
61            self,
62            JJError::CommandFailed(_) | JJError::ConflictResolutionFailed(_)
63        )
64    }
65}
66
67impl From<std::io::Error> for JJError {
68    fn from(err: std::io::Error) -> Self {
69        JJError::IoError(err.to_string())
70    }
71}
72
73impl From<serde_json::Error> for JJError {
74    fn from(err: serde_json::Error) -> Self {
75        JJError::SerializationError(err.to_string())
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82
83    #[test]
84    fn test_error_display() {
85        let err = JJError::JJNotFound;
86        assert!(err.to_string().contains("jj command not found"));
87    }
88
89    #[test]
90    fn test_recoverable() {
91        assert!(JJError::CommandFailed("test".into()).is_recoverable());
92        assert!(!JJError::JJNotFound.is_recoverable());
93    }
94}