Skip to main content

tokio_lsp/
error.rs

1//! Error types for the LSP client.
2//!
3//! This module defines all error types that can occur during LSP communication,
4//! from transport-level errors to protocol-level failures.
5
6use std::fmt;
7use thiserror::Error;
8
9/// A specialized Result type for LSP operations.
10pub type Result<T> = std::result::Result<T, LspError>;
11
12/// The main error type for LSP operations.
13#[derive(Error, Debug)]
14pub enum LspError {
15    /// IO errors from the transport layer
16    #[error("IO error: {0}")]
17    Io(#[from] std::io::Error),
18
19    /// JSON serialization/deserialization errors
20    #[error("JSON error: {0}")]
21    Json(#[from] serde_json::Error),
22
23    /// Protocol-level errors as defined by the LSP specification
24    #[error("LSP protocol error: {0}")]
25    Protocol(#[from] ResponseError),
26
27    /// Transport protocol errors (malformed headers, etc.)
28    #[error("Transport error: {0}")]
29    Transport(String),
30
31    /// Connection errors
32    #[error("Connection error: {0}")]
33    Connection(String),
34
35    /// Request timeout
36    #[error("Request timeout")]
37    Timeout,
38
39    /// Server initialization failed
40    #[error("Server initialization failed: {0}")]
41    InitializationFailed(String),
42
43    /// Generic error for other cases
44    #[error("LSP error: {0}")]
45    Other(String),
46}
47
48/// LSP ResponseError as defined by the JSON-RPC specification.
49/// This corresponds to the error object in LSP response messages.
50#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
51pub struct ResponseError {
52    /// A number indicating the error type that occurred.
53    pub code: i32,
54    /// A string providing a short description of the error.
55    pub message: String,
56    /// A primitive or structured value that contains additional information about the error.
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub data: Option<serde_json::Value>,
59}
60
61impl fmt::Display for ResponseError {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        write!(f, "Error {}: {}", self.code, self.message)
64    }
65}
66
67impl std::error::Error for ResponseError {}
68
69/// Error codes as defined by the LSP specification.
70pub mod error_codes {
71    // JSON RPC error codes
72    pub const PARSE_ERROR: i32 = -32700;
73    pub const INVALID_REQUEST: i32 = -32600;
74    pub const METHOD_NOT_FOUND: i32 = -32601;
75    pub const INVALID_PARAMS: i32 = -32602;
76    pub const INTERNAL_ERROR: i32 = -32603;
77
78    // JSON RPC reserved error range
79    pub const JSONRPC_RESERVED_ERROR_RANGE_START: i32 = -32099;
80    pub const SERVER_NOT_INITIALIZED: i32 = -32002;
81    pub const UNKNOWN_ERROR_CODE: i32 = -32001;
82    pub const JSONRPC_RESERVED_ERROR_RANGE_END: i32 = -32000;
83
84    // LSP reserved error range
85    pub const LSP_RESERVED_ERROR_RANGE_START: i32 = -32899;
86    pub const CONTENT_MODIFIED: i32 = -32801;
87    pub const REQUEST_CANCELLED: i32 = -32800;
88    pub const LSP_RESERVED_ERROR_RANGE_END: i32 = -32800;
89}
90
91impl ResponseError {
92    /// Create a new ResponseError with the given code and message.
93    pub fn new(code: i32, message: impl Into<String>) -> Self {
94        Self {
95            code,
96            message: message.into(),
97            data: None,
98        }
99    }
100
101    /// Create a new ResponseError with additional data.
102    pub fn with_data(code: i32, message: impl Into<String>, data: serde_json::Value) -> Self {
103        Self {
104            code,
105            message: message.into(),
106            data: Some(data),
107        }
108    }
109
110    /// Create a parse error.
111    pub fn parse_error(message: impl Into<String>) -> Self {
112        Self::new(error_codes::PARSE_ERROR, message)
113    }
114
115    /// Create an invalid request error.
116    pub fn invalid_request(message: impl Into<String>) -> Self {
117        Self::new(error_codes::INVALID_REQUEST, message)
118    }
119
120    /// Create a method not found error.
121    pub fn method_not_found(message: impl Into<String>) -> Self {
122        Self::new(error_codes::METHOD_NOT_FOUND, message)
123    }
124
125    /// Create an invalid params error.
126    pub fn invalid_params(message: impl Into<String>) -> Self {
127        Self::new(error_codes::INVALID_PARAMS, message)
128    }
129
130    /// Create an internal error.
131    pub fn internal_error(message: impl Into<String>) -> Self {
132        Self::new(error_codes::INTERNAL_ERROR, message)
133    }
134
135    /// Create a server not initialized error.
136    pub fn server_not_initialized(message: impl Into<String>) -> Self {
137        Self::new(error_codes::SERVER_NOT_INITIALIZED, message)
138    }
139
140    /// Create a request cancelled error.
141    pub fn request_cancelled(message: impl Into<String>) -> Self {
142        Self::new(error_codes::REQUEST_CANCELLED, message)
143    }
144
145    /// Create a content modified error.
146    pub fn content_modified(message: impl Into<String>) -> Self {
147        Self::new(error_codes::CONTENT_MODIFIED, message)
148    }
149}