claude_agent_sdk/
error.rs

1//! Error types for the Claude Agent SDK
2
3use thiserror::Error;
4
5/// Main error type for the Claude Agent SDK
6#[derive(Error, Debug)]
7pub enum ClaudeError {
8    /// Claude Code CLI not found or not installed
9    #[error("Claude Code CLI not found: {0}")]
10    CliNotFound(String),
11
12    /// Connection error when communicating with Claude Code
13    #[error("Connection error: {0}")]
14    Connection(String),
15
16    /// Process execution error with exit code and stderr
17    #[error("Process error (exit code {exit_code}): {message}")]
18    Process {
19        /// Error message
20        message: String,
21        /// Process exit code
22        exit_code: i32,
23        /// Standard error output
24        stderr: Option<String>,
25    },
26
27    /// JSON decode error when parsing CLI output
28    #[error("JSON decode error: {0}")]
29    JsonDecode(#[from] serde_json::Error),
30
31    /// Message parse error with optional raw data
32    #[error("Message parse error: {message}")]
33    MessageParse {
34        /// Error message
35        message: String,
36        /// Raw message data that failed to parse
37        data: Option<serde_json::Value>,
38    },
39
40    /// Transport layer error
41    #[error("Transport error: {0}")]
42    Transport(String),
43
44    /// Control protocol error
45    #[error("Control protocol error: {0}")]
46    ControlProtocol(String),
47
48    /// Hook execution error
49    #[error("Hook error: {0}")]
50    Hook(String),
51
52    /// MCP (Model Context Protocol) error
53    #[error("MCP error: {0}")]
54    Mcp(String),
55
56    /// I/O error
57    #[error("IO error: {0}")]
58    Io(#[from] std::io::Error),
59
60    /// Timeout error
61    #[error("Timeout: {0}")]
62    Timeout(String),
63
64    /// Invalid configuration
65    #[error("Invalid configuration: {0}")]
66    InvalidConfig(String),
67}
68
69/// Result type alias for Claude SDK operations
70pub type Result<T> = std::result::Result<T, ClaudeError>;
71
72impl ClaudeError {
73    /// Create a CLI not found error with a helpful message
74    pub fn cli_not_found() -> Self {
75        Self::CliNotFound(
76            "Claude Code not found. Install with:\n\
77             npm install -g @anthropic-ai/claude-code\n\
78             \n\
79             If already installed locally, try:\n\
80             export PATH=\"$HOME/node_modules/.bin:$PATH\"\n\
81             \n\
82             Or specify the path when creating transport"
83                .to_string(),
84        )
85    }
86
87    /// Create a connection error
88    pub fn connection(msg: impl Into<String>) -> Self {
89        Self::Connection(msg.into())
90    }
91
92    /// Create a process error
93    pub fn process(msg: impl Into<String>, exit_code: i32, stderr: Option<String>) -> Self {
94        Self::Process {
95            message: msg.into(),
96            exit_code,
97            stderr,
98        }
99    }
100
101    /// Create a message parse error
102    pub fn message_parse(msg: impl Into<String>, data: Option<serde_json::Value>) -> Self {
103        Self::MessageParse {
104            message: msg.into(),
105            data,
106        }
107    }
108
109    /// Create a transport error
110    pub fn transport(msg: impl Into<String>) -> Self {
111        Self::Transport(msg.into())
112    }
113
114    /// Create a control protocol error
115    pub fn control_protocol(msg: impl Into<String>) -> Self {
116        Self::ControlProtocol(msg.into())
117    }
118
119    /// Alias for control_protocol - used by protocol handler
120    pub fn protocol_error(msg: impl Into<String>) -> Self {
121        Self::ControlProtocol(msg.into())
122    }
123
124    /// Create a JSON encode error
125    pub fn json_encode(msg: impl Into<String>) -> Self {
126        Self::JsonDecode(serde_json::Error::io(std::io::Error::new(
127            std::io::ErrorKind::InvalidData,
128            msg.into(),
129        )))
130    }
131
132    /// Create a JSON decode error from string
133    pub fn json_decode(msg: impl Into<String>) -> Self {
134        Self::JsonDecode(serde_json::Error::io(std::io::Error::new(
135            std::io::ErrorKind::InvalidData,
136            msg.into(),
137        )))
138    }
139
140    /// Create a hook error
141    pub fn hook(msg: impl Into<String>) -> Self {
142        Self::Hook(msg.into())
143    }
144
145    /// Create an MCP error
146    pub fn mcp(msg: impl Into<String>) -> Self {
147        Self::Mcp(msg.into())
148    }
149
150    /// Create a timeout error
151    pub fn timeout(msg: impl Into<String>) -> Self {
152        Self::Timeout(msg.into())
153    }
154
155    /// Create an invalid configuration error
156    pub fn invalid_config(msg: impl Into<String>) -> Self {
157        Self::InvalidConfig(msg.into())
158    }
159}