From b7d757405fe14c924baefbdedd785e4c6a7a0f88 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Fri, 1 Apr 2022 10:57:54 -0400 Subject: [PATCH] internal/lsp/protocol: avoid replying with non-nil interface values in case of error The JSON-RPC 2.0 protocol requires that responses objects have either a "result" or an "error", but not both. In Go, this corresponds to a non-nil result interface value or a non-nil error. However, the generated wrappers for the LSP protocol were passing non-nil values for both in case of error, due to passing typed-nil pointers as (non-nil) interfaces (see https://go.dev/doc/faq#nil_error). This change fixes the generator to explicitly pass only one or the other, and re-runs the generator at the existing commit. For golang/go#49387 For golang/go#46520 Change-Id: I582b52820bdac15d9f947e8d6c1e9daa70c53e40 Reviewed-on: https://go-review.googlesource.com/c/tools/+/388600 Run-TryBot: Bryan Mills Reviewed-by: Ian Cottrell gopls-CI: kokoro TryBot-Result: Gopher Robot --- internal/lsp/protocol/tsclient.go | 27 ++- internal/lsp/protocol/tsprotocol.go | 2 +- internal/lsp/protocol/tsserver.go | 252 ++++++++++++++++++----- internal/lsp/protocol/typescript/code.ts | 5 +- 4 files changed, 227 insertions(+), 59 deletions(-) diff --git a/internal/lsp/protocol/tsclient.go b/internal/lsp/protocol/tsclient.go index 004cad93be..c80a4c9ec7 100644 --- a/internal/lsp/protocol/tsclient.go +++ b/internal/lsp/protocol/tsclient.go @@ -9,7 +9,7 @@ package protocol // Package protocol contains data types and code for LSP json rpcs // generated automatically from vscode-languageserver-node // commit: 696f9285bf849b73745682fdb1c1feac73eb8772 -// last fetched Fri Mar 04 2022 14:48:10 GMT-0500 (Eastern Standard Time) +// last fetched Fri Apr 01 2022 10:53:41 GMT-0400 (Eastern Daylight Time) import ( "context" @@ -77,14 +77,20 @@ func clientDispatch(ctx context.Context, client Client, reply jsonrpc2.Replier, return true, reply(ctx, nil, errors.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)) } resp, err := client.WorkspaceFolders(ctx) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "workspace/configuration": // req var params ParamConfiguration if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := client.Configuration(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "window/workDoneProgress/create": // req var params WorkDoneProgressCreateParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { @@ -98,7 +104,10 @@ func clientDispatch(ctx context.Context, client Client, reply jsonrpc2.Replier, return true, sendParseError(ctx, reply, err) } resp, err := client.ShowDocument(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "client/registerCapability": // req var params RegistrationParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { @@ -119,14 +128,20 @@ func clientDispatch(ctx context.Context, client Client, reply jsonrpc2.Replier, return true, sendParseError(ctx, reply, err) } resp, err := client.ShowMessageRequest(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "workspace/applyEdit": // req var params ApplyWorkspaceEditParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := client.ApplyEdit(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) default: return false, nil diff --git a/internal/lsp/protocol/tsprotocol.go b/internal/lsp/protocol/tsprotocol.go index 2438d40c36..647aabc2ee 100644 --- a/internal/lsp/protocol/tsprotocol.go +++ b/internal/lsp/protocol/tsprotocol.go @@ -7,7 +7,7 @@ // Package protocol contains data types and code for LSP json rpcs // generated automatically from vscode-languageserver-node // commit: 696f9285bf849b73745682fdb1c1feac73eb8772 -// last fetched Fri Mar 04 2022 14:48:10 GMT-0500 (Eastern Standard Time) +// last fetched Fri Apr 01 2022 10:53:41 GMT-0400 (Eastern Daylight Time) package protocol import "encoding/json" diff --git a/internal/lsp/protocol/tsserver.go b/internal/lsp/protocol/tsserver.go index db345b3e40..e0f83b76ae 100644 --- a/internal/lsp/protocol/tsserver.go +++ b/internal/lsp/protocol/tsserver.go @@ -9,7 +9,7 @@ package protocol // Package protocol contains data types and code for LSP json rpcs // generated automatically from vscode-languageserver-node // commit: 696f9285bf849b73745682fdb1c1feac73eb8772 -// last fetched Fri Mar 04 2022 14:48:10 GMT-0500 (Eastern Standard Time) +// last fetched Fri Apr 01 2022 10:53:41 GMT-0400 (Eastern Daylight Time) import ( "context" @@ -243,91 +243,130 @@ func serverDispatch(ctx context.Context, server Server, reply jsonrpc2.Replier, return true, sendParseError(ctx, reply, err) } resp, err := server.Implementation(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/typeDefinition": // req var params TypeDefinitionParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.TypeDefinition(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/documentColor": // req var params DocumentColorParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.DocumentColor(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/colorPresentation": // req var params ColorPresentationParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.ColorPresentation(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/foldingRange": // req var params FoldingRangeParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.FoldingRange(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/declaration": // req var params DeclarationParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.Declaration(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/selectionRange": // req var params SelectionRangeParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.SelectionRange(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/prepareCallHierarchy": // req var params CallHierarchyPrepareParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.PrepareCallHierarchy(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "callHierarchy/incomingCalls": // req var params CallHierarchyIncomingCallsParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.IncomingCalls(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "callHierarchy/outgoingCalls": // req var params CallHierarchyOutgoingCallsParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.OutgoingCalls(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/semanticTokens/full": // req var params SemanticTokensParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.SemanticTokensFull(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/semanticTokens/full/delta": // req var params SemanticTokensDeltaParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.SemanticTokensFullDelta(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/semanticTokens/range": // req var params SemanticTokensRangeParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.SemanticTokensRange(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "workspace/semanticTokens/refresh": // req if len(r.Params()) > 0 { return true, reply(ctx, nil, errors.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)) @@ -340,63 +379,90 @@ func serverDispatch(ctx context.Context, server Server, reply jsonrpc2.Replier, return true, sendParseError(ctx, reply, err) } resp, err := server.LinkedEditingRange(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "workspace/willCreateFiles": // req var params CreateFilesParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.WillCreateFiles(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "workspace/willRenameFiles": // req var params RenameFilesParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.WillRenameFiles(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "workspace/willDeleteFiles": // req var params DeleteFilesParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.WillDeleteFiles(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/moniker": // req var params MonikerParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.Moniker(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/prepareTypeHierarchy": // req var params TypeHierarchyPrepareParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.PrepareTypeHierarchy(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "typeHierarchy/supertypes": // req var params TypeHierarchySupertypesParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.Supertypes(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "typeHierarchy/subtypes": // req var params TypeHierarchySubtypesParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.Subtypes(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/inlineValue": // req var params InlineValueParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.InlineValue(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "workspace/inlineValue/refresh": // req if len(r.Params()) > 0 { return true, reply(ctx, nil, errors.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)) @@ -409,14 +475,20 @@ func serverDispatch(ctx context.Context, server Server, reply jsonrpc2.Replier, return true, sendParseError(ctx, reply, err) } resp, err := server.InlayHint(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "inlayHint/resolve": // req var params InlayHint if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.Resolve(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "workspace/inlayHint/refresh": // req if len(r.Params()) > 0 { return true, reply(ctx, nil, errors.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)) @@ -431,7 +503,10 @@ func serverDispatch(ctx context.Context, server Server, reply jsonrpc2.Replier, } } resp, err := server.Initialize(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "shutdown": // req if len(r.Params()) > 0 { return true, reply(ctx, nil, errors.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)) @@ -444,105 +519,150 @@ func serverDispatch(ctx context.Context, server Server, reply jsonrpc2.Replier, return true, sendParseError(ctx, reply, err) } resp, err := server.WillSaveWaitUntil(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/completion": // req var params CompletionParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.Completion(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "completionItem/resolve": // req var params CompletionItem if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.ResolveCompletionItem(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/hover": // req var params HoverParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.Hover(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/signatureHelp": // req var params SignatureHelpParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.SignatureHelp(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/definition": // req var params DefinitionParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.Definition(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/references": // req var params ReferenceParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.References(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/documentHighlight": // req var params DocumentHighlightParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.DocumentHighlight(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/documentSymbol": // req var params DocumentSymbolParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.DocumentSymbol(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/codeAction": // req var params CodeActionParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.CodeAction(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "codeAction/resolve": // req var params CodeAction if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.ResolveCodeAction(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "workspace/symbol": // req var params WorkspaceSymbolParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.Symbol(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "workspaceSymbol/resolve": // req var params WorkspaceSymbol if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.ResolveWorkspaceSymbol(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/codeLens": // req var params CodeLensParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.CodeLens(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "codeLens/resolve": // req var params CodeLens if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.ResolveCodeLens(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "workspace/codeLens/refresh": // req if len(r.Params()) > 0 { return true, reply(ctx, nil, errors.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)) @@ -555,70 +675,100 @@ func serverDispatch(ctx context.Context, server Server, reply jsonrpc2.Replier, return true, sendParseError(ctx, reply, err) } resp, err := server.DocumentLink(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "documentLink/resolve": // req var params DocumentLink if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.ResolveDocumentLink(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/formatting": // req var params DocumentFormattingParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.Formatting(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/rangeFormatting": // req var params DocumentRangeFormattingParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.RangeFormatting(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/onTypeFormatting": // req var params DocumentOnTypeFormattingParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.OnTypeFormatting(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/rename": // req var params RenameParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.Rename(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/prepareRename": // req var params PrepareRenameParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.PrepareRename(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "workspace/executeCommand": // req var params ExecuteCommandParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.ExecuteCommand(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "textDocument/diagnostic": // req var params string if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.Diagnostic(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "workspace/diagnostic": // req var params WorkspaceDiagnosticParams if err := json.Unmarshal(r.Params(), ¶ms); err != nil { return true, sendParseError(ctx, reply, err) } resp, err := server.DiagnosticWorkspace(ctx, ¶ms) - return true, reply(ctx, resp, err) + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil) case "workspace/diagnostic/refresh": // req if len(r.Params()) > 0 { return true, reply(ctx, nil, errors.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)) diff --git a/internal/lsp/protocol/typescript/code.ts b/internal/lsp/protocol/typescript/code.ts index dcb1b67a54..168a128eee 100644 --- a/internal/lsp/protocol/typescript/code.ts +++ b/internal/lsp/protocol/typescript/code.ts @@ -1259,7 +1259,10 @@ function goReq(side: side, m: string) { }`; if (b != '' && b != 'void') { case2 = `resp, err := ${side.name}.${nm}(ctx${arg2}) - return true, reply(ctx, resp, err)`; + if err != nil { + return true, reply(ctx, nil, err) + } + return true, reply(ctx, resp, nil)`; } else { // response is nil case2 = `err := ${side.name}.${nm}(ctx${arg2}) return true, reply(ctx, nil, err)`;