use std::io;
use thiserror::Error;
use crate::lsp::error::LspError;
use crate::workspace_paths::EmptyFilePathError;
pub use crate::file_ops::FileError;
#[doc = include_str!("../docs/coding_error.md")]
#[derive(Debug, Error)]
pub enum CodingError {
#[error(transparent)]
File(#[from] FileError),
#[error(transparent)]
Bash(#[from] BashError),
#[error(transparent)]
WebFetch(#[from] WebFetchError),
#[error(transparent)]
WebSearch(#[from] WebSearchError),
#[error(transparent)]
Lsp(#[from] LspError),
#[error("{0} is not configured")]
NotConfigured(&'static str),
#[error(transparent)]
EmptyFilePath(#[from] EmptyFilePathError),
#[error(
"Safety check failed: File '{0}' already exists. You must use read_file on it before overwriting. This prevents accidental data loss."
)]
NotReadBeforeOverwrite(String),
#[error(
"Safety check failed: You must use read_file on '{0}' before editing it. This ensures you understand the current file contents before making changes."
)]
NotReadBeforeEdit(String),
#[error("Failed to check existence of {path}: {source}")]
ExistsCheckFailed { path: String, source: io::Error },
}
impl rmcp::model::IntoContents for CodingError {
fn into_contents(self) -> Vec<rmcp::model::ContentBlock> {
vec![rmcp::model::ContentBlock::text(self.to_string())]
}
}
#[derive(Debug, Error)]
pub enum BashError {
#[error("{0}")]
Forbidden(String),
#[error("Timeout cannot exceed 600000ms (10 minutes)")]
TimeoutTooLarge,
#[error("Failed to execute command '{command}': {reason}")]
SpawnFailed { command: String, reason: String },
}
#[derive(Debug, Clone, Error)]
pub enum WebFetchError {
#[error("Invalid URL: {0}")]
InvalidUrl(#[source] url::ParseError),
#[error("Request failed: {0}")]
RequestFailed(String),
#[error("Request timed out after {0}ms")]
Timeout(u64),
}
#[derive(Debug, Clone, Error)]
pub enum WebSearchError {
#[error("Invalid search query: {0}")]
InvalidQuery(String),
#[error("API request failed: {0}")]
ApiError(String),
#[error("Rate limit exceeded: {message}")]
RateLimited { message: String, retry_after: Option<std::time::Duration> },
#[error("Request timed out after {0}ms")]
Timeout(u64),
#[error("Configuration error: {0}")]
ConfigError(String),
#[error("Failed to parse API response: {0}")]
ParseError(String),
}