use std::fmt;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, LspError>;
#[derive(Error, Debug)]
pub enum LspError {
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("LSP protocol error: {0}")]
Protocol(#[from] ResponseError),
#[error("Transport error: {0}")]
Transport(String),
#[error("Connection error: {0}")]
Connection(String),
#[error("Request timeout")]
Timeout,
#[error("Server initialization failed: {0}")]
InitializationFailed(String),
#[error("LSP error: {0}")]
Other(String),
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ResponseError {
pub code: i32,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<serde_json::Value>,
}
impl fmt::Display for ResponseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Error {}: {}", self.code, self.message)
}
}
impl std::error::Error for ResponseError {}
pub mod error_codes {
pub const PARSE_ERROR: i32 = -32700;
pub const INVALID_REQUEST: i32 = -32600;
pub const METHOD_NOT_FOUND: i32 = -32601;
pub const INVALID_PARAMS: i32 = -32602;
pub const INTERNAL_ERROR: i32 = -32603;
pub const JSONRPC_RESERVED_ERROR_RANGE_START: i32 = -32099;
pub const SERVER_NOT_INITIALIZED: i32 = -32002;
pub const UNKNOWN_ERROR_CODE: i32 = -32001;
pub const JSONRPC_RESERVED_ERROR_RANGE_END: i32 = -32000;
pub const LSP_RESERVED_ERROR_RANGE_START: i32 = -32899;
pub const CONTENT_MODIFIED: i32 = -32801;
pub const REQUEST_CANCELLED: i32 = -32800;
pub const LSP_RESERVED_ERROR_RANGE_END: i32 = -32800;
}
impl ResponseError {
pub fn new(code: i32, message: impl Into<String>) -> Self {
Self {
code,
message: message.into(),
data: None,
}
}
pub fn with_data(code: i32, message: impl Into<String>, data: serde_json::Value) -> Self {
Self {
code,
message: message.into(),
data: Some(data),
}
}
pub fn parse_error(message: impl Into<String>) -> Self {
Self::new(error_codes::PARSE_ERROR, message)
}
pub fn invalid_request(message: impl Into<String>) -> Self {
Self::new(error_codes::INVALID_REQUEST, message)
}
pub fn method_not_found(message: impl Into<String>) -> Self {
Self::new(error_codes::METHOD_NOT_FOUND, message)
}
pub fn invalid_params(message: impl Into<String>) -> Self {
Self::new(error_codes::INVALID_PARAMS, message)
}
pub fn internal_error(message: impl Into<String>) -> Self {
Self::new(error_codes::INTERNAL_ERROR, message)
}
pub fn server_not_initialized(message: impl Into<String>) -> Self {
Self::new(error_codes::SERVER_NOT_INITIALIZED, message)
}
pub fn request_cancelled(message: impl Into<String>) -> Self {
Self::new(error_codes::REQUEST_CANCELLED, message)
}
pub fn content_modified(message: impl Into<String>) -> Self {
Self::new(error_codes::CONTENT_MODIFIED, message)
}
}