coderlib 0.1.0

A Rust library for AI-powered code assistance and agentic system
Documentation
//! Error types for CoderLib
//!
//! This module defines the main error types used throughout the library.

use thiserror::Error;

/// Main error type for CoderLib operations
#[derive(Error, Debug)]
pub enum CoderLibError {
    /// Configuration-related errors
    #[error("Configuration error: {0}")]
    Config(#[from] ConfigError),

    /// LLM provider errors
    #[error("Provider error: {0}")]
    Provider(#[from] ProviderError),

    /// Storage/database errors
    #[error("Storage error: {0}")]
    Storage(#[from] StorageError),

    /// Tool execution errors
    #[error("Tool error: {0}")]
    Tool(#[from] crate::tools::ToolError),

    /// Session management errors
    #[error("Session error: {0}")]
    Session(#[from] SessionError),

    /// Integration errors
    #[error("Integration error: {0}")]
    Integration(#[from] IntegrationError),

    /// LSP errors
    #[error("LSP error: {0}")]
    Lsp(#[from] crate::lsp::LspError),

    /// Permission errors
    #[error("Permission error: {0}")]
    Permission(#[from] crate::permission::PermissionError),

    /// Permission denied
    #[error("Permission denied: {0}")]
    PermissionDenied(String),

    /// IO errors
    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),

    /// JSON serialization errors
    #[error("JSON error: {0}")]
    Json(#[from] serde_json::Error),

    /// Generic errors
    #[error("Internal error: {0}")]
    Internal(String),

    /// Request was cancelled
    #[error("Request was cancelled")]
    Cancelled,

    /// Invalid input
    #[error("Invalid input: {0}")]
    InvalidInput(String),
}

/// Configuration-related errors
#[derive(Error, Debug)]
pub enum ConfigError {
    #[error("Missing required configuration: {0}")]
    MissingRequired(String),

    #[error("Invalid configuration value: {0}")]
    InvalidValue(String),

    #[error("Failed to load configuration file: {0}")]
    LoadFailed(String),

    #[error("Failed to parse configuration: {0}")]
    ParseFailed(String),

    #[error("Environment variable error: {0}")]
    Environment(String),
}

/// LLM provider errors
#[derive(Error, Debug)]
pub enum ProviderError {
    #[error("HTTP request failed: {0}")]
    Http(#[from] reqwest::Error),

    #[error("Authentication failed: {0}")]
    Authentication(String),

    #[error("Rate limit exceeded: {0}")]
    RateLimit(String),

    #[error("Model not found: {0}")]
    ModelNotFound(String),

    #[error("Invalid request: {0}")]
    InvalidRequest(String),

    #[error("Provider unavailable: {0}")]
    Unavailable(String),

    #[error("Configuration error: {0}")]
    Configuration(String),

    #[error("Network error: {0}")]
    NetworkError(String),

    #[error("API error: {0}")]
    ApiError(String),

    #[error("Response parsing failed: {0}")]
    ResponseParsing(String),

    #[error("Streaming error: {0}")]
    Streaming(String),

    #[error("Token limit exceeded")]
    TokenLimitExceeded,

    #[error("Content filtered: {0}")]
    ContentFiltered(String),
}

/// Storage/database errors
#[derive(Error, Debug)]
pub enum StorageError {
    #[error("Database error: {0}")]
    Database(#[from] sqlx::Error),

    #[error("Migration failed: {0}")]
    Migration(String),

    #[error("Connection failed: {0}")]
    Connection(String),

    #[error("Transaction failed: {0}")]
    Transaction(String),

    #[error("Data not found: {0}")]
    NotFound(String),

    #[error("Data corruption detected: {0}")]
    Corruption(String),

    #[error("Storage initialization failed: {0}")]
    Initialization(String),

    #[error("Serialization error: {0}")]
    Serialization(String),
}



/// Session management errors
#[derive(Error, Debug)]
pub enum SessionError {
    #[error("Session not found: {0}")]
    NotFound(String),

    #[error("Session creation failed: {0}")]
    CreationFailed(String),

    #[error("Session already exists: {0}")]
    AlreadyExists(String),

    #[error("Session is locked: {0}")]
    Locked(String),

    #[error("Session expired: {0}")]
    Expired(String),

    #[error("Invalid session state: {0}")]
    InvalidState(String),
}

/// Integration errors
#[derive(Error, Debug)]
pub enum IntegrationError {
    #[error("Host integration not available")]
    NotAvailable,

    #[error("Communication failed: {0}")]
    Communication(String),

    #[error("Protocol error: {0}")]
    Protocol(String),

    #[error("Version mismatch: {0}")]
    VersionMismatch(String),

    #[error("Feature not supported: {0}")]
    NotSupported(String),

    #[error("Callback failed: {0}")]
    CallbackFailed(String),

    #[error("Operation failed: {0}")]
    OperationFailed(String),

    #[error("File not found: {0}")]
    FileNotFound(std::path::PathBuf),
}

impl From<&str> for CoderLibError {
    fn from(s: &str) -> Self {
        CoderLibError::Internal(s.to_string())
    }
}

impl From<String> for CoderLibError {
    fn from(s: String) -> Self {
        CoderLibError::Internal(s)
    }
}

// Convenience result types
pub type ConfigResult<T> = Result<T, ConfigError>;
pub type ProviderResult<T> = Result<T, ProviderError>;
pub type StorageResult<T> = Result<T, StorageError>;
pub type ToolResult<T> = Result<T, crate::tools::ToolError>;
pub type SessionResult<T> = Result<T, SessionError>;
pub type IntegrationResult<T> = Result<T, IntegrationError>;

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_error_conversion() {
        let config_error = ConfigError::MissingRequired("api_key".to_string());
        let coder_error: CoderLibError = config_error.into();
        
        match coder_error {
            CoderLibError::Config(_) => (),
            _ => panic!("Expected Config error"),
        }
    }

    #[test]
    fn test_error_display() {
        let error = CoderLibError::InvalidInput("test input".to_string());
        assert!(error.to_string().contains("Invalid input"));
    }

    #[test]
    fn test_string_conversion() {
        let error: CoderLibError = "test error".into();
        match error {
            CoderLibError::Internal(msg) => assert_eq!(msg, "test error"),
            _ => panic!("Expected Internal error"),
        }
    }
}