lsp: Only mute RequestCancelled or ContentModified, but not other errors

handlers passed to `lsp_buf_request` weren't called if the server
responded with an error that looks like this:

     "decoded", {
      error = {
        code = -32601,
        message = "No delegateCommandHandler for foo"
      },
      id = 5,
      jsonrpc = "2.0"
    }

An example where that happens is both eclipse.jdt.ls and the
haskell-language-server when invoking a command that doesn't exist:

    :lua vim.lsp.buf_request(
      0,
      'workspace/executeCommand',
      { command = 'foo' },
      function(err, _, res)
        print(vim.inspect(err), vim.inspect(res))
      end
    )
This commit is contained in:
Mathias Fussenegger
2021-05-23 16:56:02 +02:00
parent 3fb3b548a6
commit 5d4717010c

View File

@@ -523,27 +523,33 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params)
decoded.error = convert_NIL(decoded.error)
decoded.result = convert_NIL(decoded.result)
-- Do not surface RequestCancelled or ContentModified to users, it is RPC-internal.
if decoded.error then
if decoded.error.code == protocol.ErrorCodes.RequestCancelled then
local _ = log.debug() and log.debug("Received cancellation ack", decoded)
elseif decoded.error.code == protocol.ErrorCodes.ContentModified then
local _ = log.debug() and log.debug("Received content modified ack", decoded)
end
local result_id = tonumber(decoded.id)
-- Clear any callback since this is cancelled now.
-- This is safe to do assuming that these conditions hold:
-- - The server will not send a result callback after this cancellation.
-- - If the server sent this cancellation ACK after sending the result, the user of this RPC
-- client will ignore the result themselves.
if result_id then
message_callbacks[result_id] = nil
end
return
end
-- We sent a number, so we expect a number.
local result_id = tonumber(decoded.id)
-- Do not surface RequestCancelled or ContentModified to users, it is RPC-internal.
if decoded.error then
local mute_error = false
if decoded.error.code == protocol.ErrorCodes.RequestCancelled then
local _ = log.debug() and log.debug("Received cancellation ack", decoded)
mute_error = true
elseif decoded.error.code == protocol.ErrorCodes.ContentModified then
local _ = log.debug() and log.debug("Received content modified ack", decoded)
mute_error = true
end
if mute_error then
-- Clear any callback since this is cancelled now.
-- This is safe to do assuming that these conditions hold:
-- - The server will not send a result callback after this cancellation.
-- - If the server sent this cancellation ACK after sending the result, the user of this RPC
-- client will ignore the result themselves.
if result_id then
message_callbacks[result_id] = nil
end
return
end
end
local callback = message_callbacks[result_id]
if callback then
message_callbacks[result_id] = nil