Skip to content

Commit

Permalink
fix: handle ResponseErrors correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
dimbleby authored and tombh committed Nov 26, 2023
1 parent ccec102 commit a590d30
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 17 deletions.
11 changes: 3 additions & 8 deletions pygls/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import traceback
from typing import Set
from typing import Type
from lsprotocol.types import ResponseError


class JsonRpcException(Exception):
Expand Down Expand Up @@ -56,14 +57,8 @@ def supports_code(cls, code):
# Defaults to UnknownErrorCode
return getattr(cls, "CODE", -32001) == code

def to_dict(self):
exception_dict = {
"code": self.code,
"message": self.message,
}
if self.data is not None:
exception_dict["data"] = str(self.data)
return exception_dict
def to_response_error(self) -> ResponseError:
return ResponseError(code=self.code, message=self.message, data=self.data)


class JsonRpcInternalError(JsonRpcException):
Expand Down
21 changes: 12 additions & 9 deletions pygls/protocol/json_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
CANCEL_REQUEST,
EXIT,
WORKSPACE_EXECUTE_COMMAND,
ResponseError,
ResponseErrorMessage,
)

Expand Down Expand Up @@ -157,7 +158,7 @@ def _execute_notification_callback(self, future):
try:
raise future.exception()
except Exception:
error = JsonRpcInternalError.of(sys.exc_info()).to_dict()
error = JsonRpcInternalError.of(sys.exc_info())
logger.exception('Exception occurred in notification: "%s"', error)

# Revisit. Client does not support response with msg_id = None
Expand Down Expand Up @@ -196,20 +197,20 @@ def _execute_request_callback(self, msg_id, future):
msg_id,
error=JsonRpcRequestCancelled(
f'Request with id "{msg_id}" is canceled'
),
).to_response_error(),
)
self._request_futures.pop(msg_id, None)
except Exception:
error = JsonRpcInternalError.of(sys.exc_info()).to_dict()
error = JsonRpcInternalError.of(sys.exc_info())
logger.exception('Exception occurred for message "%s": %s', msg_id, error)
self._send_response(msg_id, error=error)
self._send_response(msg_id, error=error.to_response_error())

def _execute_request_err_callback(self, msg_id, exc):
"""Error callback used for coroutine request message."""
exc_info = (type(exc), exc, None)
error = JsonRpcInternalError.of(exc_info).to_dict()
error = JsonRpcInternalError.of(exc_info)
logger.exception('Exception occurred for message "%s": %s', msg_id, error)
self._send_response(msg_id, error=error)
self._send_response(msg_id, error=error.to_response_error())

def _get_handler(self, feature_name):
"""Returns builtin or used defined feature by name if exists."""
Expand Down Expand Up @@ -272,7 +273,7 @@ def _handle_request(self, msg_id, method_name, params):
params,
exc_info=True,
)
self._send_response(msg_id, None, error.to_dict())
self._send_response(msg_id, None, error.to_response_error())
self._server._report_server_error(error, FeatureRequestError)
except Exception as error:
logger.exception(
Expand All @@ -282,7 +283,7 @@ def _handle_request(self, msg_id, method_name, params):
params,
exc_info=True,
)
err = JsonRpcInternalError.of(sys.exc_info()).to_dict()
err = JsonRpcInternalError.of(sys.exc_info()).to_response_error()
self._send_response(msg_id, None, err)
self._server._report_server_error(error, FeatureRequestError)

Expand Down Expand Up @@ -401,7 +402,9 @@ def _send_data(self, data):
logger.exception("Error sending data", exc_info=True)
self._server._report_server_error(error, JsonRpcInternalError)

def _send_response(self, msg_id, result=None, error=None):
def _send_response(
self, msg_id, result=None, error: Union[ResponseError, None] = None
):
"""Sends a JSON RPC response to the client.
Args:
Expand Down

0 comments on commit a590d30

Please sign in to comment.