Improve handling of unexpected errors
See original GitHub issueThis jumps off from an issue identified by @alcarney in the v1 breaking changes PR https://github.com/openlawlibrary/pygls/pull/273#issuecomment-1288146841
Pygls does already catch some errors, but not all. Nor does it offer a way for server authors to handle those unexpected errors.
@alcarney Is that a fair summarisation of the problem? Obviously the underlying message parsing problem needs to be fixed, but is it not a reflection of a deeper issue, that Pygls couldn’t recover from that error?
Recently I’ve been attempting to build a Pygls template project, that offers a reasonable and informative starting point for new custom servers. Maybe it’s my relative inexperience with Pygls, but I noticed that there doesn’t seem to be a centralised point for all error handling? My naive approach is to decorate the feature
decorator like so:
def add_feature(self, feature: str):
"""
This is a wrapper just to catch and handle all unexpected errors in one place.
TODO:
Is this even useful? I wonder if this should be formally supported in Pygls itself?
"""
def wrapper(func):
@self.feature(feature)
async def inner(*args, **kwargs):
try:
await func(*args, **kwargs)
except Exception as e:
self.logger.error(e)
# TODO: should this have the name of the custom LSP server?
self.show_message(f"Unexpected error in LSP server: {e}")
return inner
return wrapper
Does that seem relevant to the deeper issue at hand?
Issue Analytics
- State:
- Created a year ago
- Comments:5
Top GitHub Comments
Ok great, thanks for the insights 🤓 So just to sketch things out:
data_received
, like_send_data
, should have a try/catch block.except:
blocks.showMessage.type = MessageType.Error
message to the client on errors triggered by notification responses.Not saying you should do all that if you’re the first in there. Just making a note for the future.
Oh, wait! Hold the press! I’ve figured something out: errors in LSP requests and notifications are handled differently.
So, the actual formal way to handle a LSP client request is with a LSP
ResponseError
inResponseMessage.error
. Which we do already do inJsonRPCProtocol._handle_request()
✅Now, here’s the thing. LSP requests and notifications are 2 distinct things. You probably already knew that, but I’ve only just realised that now 😬 For anybody else that isn’t aware of the difference,
textDocument/didOpen
is an example of a notification, whereastextDocument/completion
is a request. And in Pygls’ case,JsonRPCProtocol._handle_notification()
does not attempt to return any errors to the client. It does however at least catch and locally log errors.So, this changes gears a little. Unchanged is that we’re still wanting to improve error handling for
data_received
. But more specifically we want to default to sendingshowMessage.type = MessageType.Error
messages to the client for notifications only. With a convenient way to override that behaviour.I’ve updated my previous comment to better reflect this new insight.