0
# Exception Handling
1
2
Exception classes for pygls error handling, JSON-RPC protocol errors, and language server specific exceptions with proper error codes and messages.
3
4
## Capabilities
5
6
### Base Exception Classes
7
8
Core exception classes that form the foundation of pygls error handling.
9
10
```python { .api }
11
class PyglsError(Exception):
12
"""
13
Base exception class for all pygls-specific errors.
14
15
Extends the standard Python Exception class to provide
16
a common base for all pygls-related exceptions.
17
"""
18
19
class JsonRpcException(Exception):
20
"""
21
Base JSON-RPC exception with error code and message.
22
23
Provides structured error information for JSON-RPC
24
protocol violations and communication errors.
25
"""
26
27
def __init__(self, code: int, message: str, data: Any = None): ...
28
```
29
30
### JSON-RPC Protocol Exceptions
31
32
Standard JSON-RPC error codes and exceptions as defined in the JSON-RPC 2.0 specification.
33
34
```python { .api }
35
class JsonRpcParseError(JsonRpcException):
36
"""Parse error (-32700) - Invalid JSON received."""
37
38
class JsonRpcInvalidRequest(JsonRpcException):
39
"""Invalid request (-32600) - JSON is not a valid request object."""
40
41
class JsonRpcMethodNotFound(JsonRpcException):
42
"""Method not found (-32601) - Method does not exist or is not available."""
43
44
class JsonRpcInvalidParams(JsonRpcException):
45
"""Invalid parameters (-32602) - Invalid method parameters."""
46
47
class JsonRpcInternalError(JsonRpcException):
48
"""Internal error (-32603) - Internal JSON-RPC error."""
49
```
50
51
### LSP-Specific JSON-RPC Exceptions
52
53
Language Server Protocol specific error codes and exceptions.
54
55
```python { .api }
56
class JsonRpcServerNotInitialized(JsonRpcException):
57
"""Server not initialized (-32002) - Server received request before initialize."""
58
59
class JsonRpcUnknownErrorCode(JsonRpcException):
60
"""Unknown error code (-32001) - Unknown error."""
61
62
class JsonRpcRequestCancelled(JsonRpcException):
63
"""Request cancelled (-32800) - Request was cancelled."""
64
65
class JsonRpcContentModified(JsonRpcException):
66
"""Content modified (-32801) - Content was modified while processing request."""
67
```
68
69
### Reserved Error Range Exceptions
70
71
Exceptions for JSON-RPC and LSP reserved error code ranges.
72
73
```python { .api }
74
class JsonRpcReservedErrorRangeStart(JsonRpcException):
75
"""Reserved error range start (-32099)."""
76
77
class JsonRpcReservedErrorRangeEnd(JsonRpcException):
78
"""Reserved error range end (-32000)."""
79
80
class LspReservedErrorRangeStart(JsonRpcException):
81
"""LSP reserved error range start (-32899)."""
82
83
class LspReservedErrorRangeEnd(JsonRpcException):
84
"""LSP reserved error range end (-32800)."""
85
86
class JsonRpcServerError(JsonRpcException):
87
"""Server error (custom range -32099 to -32000)."""
88
```
89
90
### pygls Feature Exceptions
91
92
Exceptions specific to pygls feature registration and execution.
93
94
```python { .api }
95
class FeatureAlreadyRegisteredError(PyglsError):
96
"""
97
Exception raised when attempting to register a feature that is already registered.
98
99
Prevents duplicate feature registration which could cause conflicts
100
in method resolution and handler execution.
101
"""
102
103
class FeatureRequestError(PyglsError):
104
"""
105
Exception raised during feature request handling.
106
107
Used to wrap and propagate errors that occur during the
108
execution of registered LSP feature handlers.
109
"""
110
111
class FeatureNotificationError(PyglsError):
112
"""
113
Exception raised during feature notification handling.
114
115
Used to wrap and propagate errors that occur during the
116
execution of registered LSP notification handlers.
117
"""
118
119
class CommandAlreadyRegisteredError(PyglsError):
120
"""
121
Exception raised when attempting to register a command that is already registered.
122
123
Prevents duplicate command registration which could cause conflicts
124
in command resolution and handler execution.
125
"""
126
```
127
128
### Protocol and Type Exceptions
129
130
Exceptions related to protocol handling and type registration.
131
132
```python { .api }
133
class MethodTypeNotRegisteredError(PyglsError):
134
"""
135
Exception raised when a method type is not registered.
136
137
Occurs when attempting to use LSP methods or features
138
that have not been properly registered with the server.
139
"""
140
141
class ThreadDecoratorError(PyglsError):
142
"""
143
Exception raised when there are issues with thread decorator usage.
144
145
Occurs when the @thread decorator is used incorrectly or
146
when thread pool configuration issues prevent proper execution.
147
"""
148
149
class ValidationError(PyglsError):
150
"""
151
Exception raised during data validation.
152
153
Used when LSP message parameters or responses fail
154
validation against their expected schemas or types.
155
"""
156
```
157
158
## Usage Examples
159
160
### Basic Exception Handling
161
162
```python
163
from pygls.server import LanguageServer
164
from pygls.exceptions import PyglsError, JsonRpcException
165
from lsprotocol.types import TEXT_DOCUMENT_COMPLETION
166
167
server = LanguageServer("exception-example", "1.0.0")
168
169
@server.feature(TEXT_DOCUMENT_COMPLETION)
170
def completion(params):
171
try:
172
# Feature implementation that might fail
173
document = server.workspace.get_document(params.text_document.uri)
174
# Process document...
175
return {"items": []}
176
except PyglsError as e:
177
# Handle pygls-specific errors
178
server.show_message(f"pygls error: {e}", MessageType.Error)
179
raise
180
except JsonRpcException as e:
181
# Handle JSON-RPC protocol errors
182
server.show_message(f"Protocol error: {e.message}", MessageType.Error)
183
raise
184
except Exception as e:
185
# Handle unexpected errors
186
server.show_message(f"Unexpected error: {e}", MessageType.Error)
187
raise JsonRpcInternalError(code=-32603, message="Internal server error")
188
```
189
190
### Feature Registration Error Handling
191
192
```python
193
from pygls.server import LanguageServer
194
from pygls.exceptions import FeatureAlreadyRegisteredError, CommandAlreadyRegisteredError
195
196
server = LanguageServer("registration-example", "1.0.0")
197
198
def safe_register_feature(feature_name, handler):
199
"""Safely register a feature with error handling."""
200
try:
201
@server.feature(feature_name)
202
def feature_handler(params):
203
return handler(params)
204
except FeatureAlreadyRegisteredError:
205
server.show_message(f"Feature {feature_name} already registered", MessageType.Warning)
206
207
def safe_register_command(command_name, handler):
208
"""Safely register a command with error handling."""
209
try:
210
@server.command(command_name)
211
def command_handler(params):
212
return handler(params)
213
except CommandAlreadyRegisteredError:
214
server.show_message(f"Command {command_name} already registered", MessageType.Warning)
215
```
216
217
### Protocol Error Handling
218
219
```python
220
from pygls.protocol import LanguageServerProtocol
221
from pygls.exceptions import (
222
JsonRpcParseError,
223
JsonRpcInvalidRequest,
224
JsonRpcMethodNotFound
225
)
226
227
class CustomProtocol(LanguageServerProtocol):
228
def handle_request(self, request):
229
try:
230
return super().handle_request(request)
231
except JsonRpcParseError:
232
# Handle JSON parsing errors
233
self.send_notification("window/logMessage", {
234
"type": 1, # Error
235
"message": "Failed to parse JSON-RPC request"
236
})
237
raise
238
except JsonRpcMethodNotFound:
239
# Handle unknown method calls
240
self.send_notification("window/logMessage", {
241
"type": 2, # Warning
242
"message": f"Unknown method: {request.get('method', 'unknown')}"
243
})
244
raise
245
```
246
247
### Validation Error Handling
248
249
```python
250
from pygls.exceptions import ValidationError
251
from lsprotocol.types import Position, Range
252
253
def validate_position(position, lines):
254
"""Validate position against document lines."""
255
if position.line < 0 or position.line >= len(lines):
256
raise ValidationError(f"Line {position.line} out of range (0-{len(lines)-1})")
257
258
line = lines[position.line]
259
if position.character < 0 or position.character > len(line):
260
raise ValidationError(f"Character {position.character} out of range (0-{len(line)})")
261
262
def validate_range(range_obj, lines):
263
"""Validate range against document lines."""
264
try:
265
validate_position(range_obj.start, lines)
266
validate_position(range_obj.end, lines)
267
268
if range_obj.start.line > range_obj.end.line:
269
raise ValidationError("Range start line cannot be after end line")
270
271
if (range_obj.start.line == range_obj.end.line and
272
range_obj.start.character > range_obj.end.character):
273
raise ValidationError("Range start character cannot be after end character")
274
275
except ValidationError:
276
# Re-raise validation errors
277
raise
278
except Exception as e:
279
# Convert other errors to validation errors
280
raise ValidationError(f"Range validation failed: {e}")
281
```
282
283
### Custom Error Reporting
284
285
```python
286
from pygls.server import LanguageServer
287
from pygls.exceptions import PyglsError
288
from lsprotocol.types import MessageType
289
290
class CustomLanguageServer(LanguageServer):
291
def report_server_error(self, error, source):
292
"""Override error reporting with custom behavior."""
293
if isinstance(error, PyglsError):
294
# Handle pygls-specific errors
295
self.show_message(f"Server error: {error}", MessageType.Error)
296
else:
297
# Handle all other errors
298
self.show_message(f"Unexpected error: {error}", MessageType.Error)
299
300
# Call parent implementation
301
super().report_server_error(error, source)
302
```