use std::path::PathBuf;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum ClaudeError {
#[error("CLI connection error: {0}")]
Connection(#[from] ConnectionError),
#[error("Process error: {0}")]
Process(#[from] ProcessError),
#[error("JSON decode error: {0}")]
JsonDecode(#[from] JsonDecodeError),
#[error("Message parse error: {0}")]
MessageParse(#[from] MessageParseError),
#[error("Transport error: {0}")]
Transport(String),
#[error("Control protocol error: {0}")]
ControlProtocol(String),
#[error("Timeout: {0}")]
Timeout(String),
#[error("Invalid configuration: {0}")]
InvalidConfig(String),
#[error("CLI not found: {0}")]
CliNotFound(#[from] CliNotFoundError),
#[error("Image validation error: {0}")]
ImageValidation(#[from] ImageValidationError),
#[error("MCP error: {0}")]
Mcp(#[from] McpError),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error(transparent)]
Other(#[from] anyhow::Error),
}
#[derive(Debug, Error)]
#[error("CLI not found: {message}")]
pub struct CliNotFoundError {
pub message: String,
pub cli_path: Option<PathBuf>,
}
impl CliNotFoundError {
pub fn new(message: impl Into<String>, cli_path: Option<PathBuf>) -> Self {
Self {
message: message.into(),
cli_path,
}
}
}
#[derive(Debug, Error)]
#[error("Connection error: {message}")]
pub struct ConnectionError {
pub message: String,
}
impl ConnectionError {
pub fn new(message: impl Into<String>) -> Self {
Self {
message: message.into(),
}
}
}
#[derive(Debug, Error)]
#[error("Process error (exit code {exit_code:?}): {message}")]
pub struct ProcessError {
pub message: String,
pub exit_code: Option<i32>,
pub stderr: Option<String>,
}
impl ProcessError {
pub fn new(message: impl Into<String>, exit_code: Option<i32>, stderr: Option<String>) -> Self {
Self {
message: message.into(),
exit_code,
stderr,
}
}
}
#[derive(Debug, Error)]
#[error("JSON decode error: {message}")]
pub struct JsonDecodeError {
pub message: String,
pub line: String,
}
impl JsonDecodeError {
pub fn new(message: impl Into<String>, line: impl Into<String>) -> Self {
Self {
message: message.into(),
line: line.into(),
}
}
}
#[derive(Debug, Error)]
#[error("Message parse error: {message}")]
pub struct MessageParseError {
pub message: String,
pub data: Option<serde_json::Value>,
}
impl MessageParseError {
pub fn new(message: impl Into<String>, data: Option<serde_json::Value>) -> Self {
Self {
message: message.into(),
data,
}
}
}
#[derive(Debug, Error)]
#[error("Image validation error: {message}")]
pub struct ImageValidationError {
pub message: String,
}
impl ImageValidationError {
pub fn new(message: impl Into<String>) -> Self {
Self {
message: message.into(),
}
}
}
#[derive(Debug, Error)]
#[error("MCP error ({code}): {message}")]
pub struct McpError {
pub code: i32,
pub message: String,
}
impl McpError {
pub fn new(code: i32, message: impl Into<String>) -> Self {
Self {
code,
message: message.into(),
}
}
pub fn method_not_found(method: &str) -> Self {
Self::new(-32601, format!("Method not found: {}", method))
}
pub fn internal_error(message: impl Into<String>) -> Self {
Self::new(-32603, message)
}
pub fn invalid_params(message: impl Into<String>) -> Self {
Self::new(-32602, message)
}
}
pub type Result<T> = std::result::Result<T, ClaudeError>;