Ignore unimplemented notifications

Responding to an unimplemented notification can cause errors for some
LSP clients that do not expect to receive a response after sending a
notification. Differentiate between unimplemented requests and
notifications and only send a generic null response for the former while
silently ignoring the latter.
This commit is contained in:
Gregory Anders 2022-06-05 13:34:02 -06:00 committed by Auguste Rame
parent ebc6de9673
commit 289d137d13

View File

@ -1637,23 +1637,31 @@ fn processJsonRpc(arena: *std.heap.ArenaAllocator, parser: *std.json.Parser, jso
else => return err, else => return err,
}; };
const unimplemented_map = std.ComptimeStringMap(void, .{ // Boolean value is true if the method is a request (and thus the client
.{"textDocument/documentHighlight"}, // needs a response) or false if the method is a notification (in which
.{"textDocument/codeAction"}, // case it should be silently ignored)
.{"textDocument/codeLens"}, const unimplemented_map = std.ComptimeStringMap(bool, .{
.{"textDocument/documentLink"}, .{ "textDocument/documentHighlight", true },
.{"textDocument/rangeFormatting"}, .{ "textDocument/codeAction", true },
.{"textDocument/onTypeFormatting"}, .{ "textDocument/codeLens", true },
.{"textDocument/prepareRename"}, .{ "textDocument/documentLink", true },
.{"textDocument/foldingRange"}, .{ "textDocument/rangeFormatting", true },
.{"textDocument/selectionRange"}, .{ "textDocument/onTypeFormatting", true },
.{"textDocument/semanticTokens/range"}, .{ "textDocument/prepareRename", true },
.{"workspace/didChangeWorkspaceFolders"}, .{ "textDocument/foldingRange", true },
.{ "textDocument/selectionRange", true },
.{ "textDocument/semanticTokens/range", true },
.{ "workspace/didChangeWorkspaceFolders", false },
}); });
if (unimplemented_map.has(method)) { if (unimplemented_map.get(method)) |request| {
// TODO: Unimplemented methods, implement them and add them to server capabilities. // TODO: Unimplemented methods, implement them and add them to server capabilities.
return try respondGeneric(id, null_result_response); if (request) {
return try respondGeneric(id, null_result_response);
}
logger.debug("Notification method {s} is not implemented", .{method});
return;
} }
if (tree.root.Object.get("id")) |_| { if (tree.root.Object.get("id")) |_| {
return try respondGeneric(id, not_implemented_response); return try respondGeneric(id, not_implemented_response);