use thiserror::Error;
#[derive(Error, Debug)]
pub enum CoderLibError {
#[error("Configuration error: {0}")]
Config(#[from] ConfigError),
#[error("Provider error: {0}")]
Provider(#[from] ProviderError),
#[error("Storage error: {0}")]
Storage(#[from] StorageError),
#[error("Tool error: {0}")]
Tool(#[from] crate::tools::ToolError),
#[error("Session error: {0}")]
Session(#[from] SessionError),
#[error("Integration error: {0}")]
Integration(#[from] IntegrationError),
#[error("LSP error: {0}")]
Lsp(#[from] crate::lsp::LspError),
#[error("Permission error: {0}")]
Permission(#[from] crate::permission::PermissionError),
#[error("Permission denied: {0}")]
PermissionDenied(String),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("Internal error: {0}")]
Internal(String),
#[error("Request was cancelled")]
Cancelled,
#[error("Invalid input: {0}")]
InvalidInput(String),
}
#[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),
}
#[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),
}
#[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),
}
#[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),
}
#[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)
}
}
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"),
}
}
}