Index: clangd/ClangdLSPServer.cpp =================================================================== --- clangd/ClangdLSPServer.cpp +++ clangd/ClangdLSPServer.cpp @@ -85,7 +85,8 @@ void ClangdLSPServer::onDocumentDidChange(Ctx C, DidChangeTextDocumentParams &Params) { if (Params.contentChanges.size() != 1) - return C.replyError(-32602, "can only apply one change at a time"); + return C.replyError(ErrorCodes::InvalidParams, + "can only apply one change at a time"); // We only support full syncing right now. Server.addDocument(Params.textDocument.uri.file, Params.contentChanges[0].text); @@ -119,7 +120,8 @@ // parsed in the first place and this handler should not be called. But if // more commands are added, this will be here has a safe guard. C.replyError( - 1, llvm::formatv("Unsupported command \"{0}\".", Params.command).str()); + ErrorCodes::InvalidParams, + llvm::formatv("Unsupported command \"{0}\".", Params.command).str()); } } @@ -191,7 +193,8 @@ Params.textDocument.uri.file, Position{Params.position.line, Params.position.character}); if (!SignatureHelp) - return C.replyError(-32602, llvm::toString(SignatureHelp.takeError())); + return C.replyError(ErrorCodes::InvalidParams, + llvm::toString(SignatureHelp.takeError())); C.reply(SignatureHelp->Value); } @@ -201,7 +204,8 @@ Params.textDocument.uri.file, Position{Params.position.line, Params.position.character}); if (!Items) - return C.replyError(-32602, llvm::toString(Items.takeError())); + return C.replyError(ErrorCodes::InvalidParams, + llvm::toString(Items.takeError())); C.reply(json::ary(Items->Value)); } @@ -228,7 +232,7 @@ // Set up JSONRPCDispatcher. JSONRPCDispatcher Dispatcher( [](RequestContext Ctx, llvm::yaml::MappingNode *Params) { - Ctx.replyError(-32601, "method not found"); + Ctx.replyError(ErrorCodes::MethodNotFound, "method not found"); }); registerCallbackHandlers(Dispatcher, Out, /*Callbacks=*/*this); Index: clangd/JSONRPCDispatcher.h =================================================================== --- clangd/JSONRPCDispatcher.h +++ clangd/JSONRPCDispatcher.h @@ -12,6 +12,7 @@ #include "JSONExpr.h" #include "Logger.h" +#include "Protocol.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" @@ -60,7 +61,7 @@ /// Sends a successful reply. void reply(json::Expr &&Result); /// Sends an error response to the client, and logs it. - void replyError(int code, const llvm::StringRef &Message); + void replyError(ErrorCodes code, const llvm::StringRef &Message); /// Sends a request to the client. void call(llvm::StringRef Method, json::Expr &&Params); Index: clangd/JSONRPCDispatcher.cpp =================================================================== --- clangd/JSONRPCDispatcher.cpp +++ clangd/JSONRPCDispatcher.cpp @@ -65,13 +65,13 @@ }); } -void RequestContext::replyError(int code, const llvm::StringRef &Message) { - Out.log("Error " + llvm::Twine(code) + ": " + Message + "\n"); +void RequestContext::replyError(ErrorCodes code, const llvm::StringRef &Message) { + Out.log("Error " + Twine(static_cast(code)) + ": " + Message + "\n"); if (ID) { Out.writeMessage(json::obj{ {"jsonrpc", "2.0"}, {"id", *ID}, - {"error", json::obj{{"code", code}, {"message", Message}}}, + {"error", json::obj{{"code", static_cast(code)}, {"message", Message}}}, }); } } Index: clangd/Protocol.h =================================================================== --- clangd/Protocol.h +++ clangd/Protocol.h @@ -32,6 +32,22 @@ class Logger; +enum class ErrorCodes { + // Defined by JSON RPC. + ParseError = -32700, + InvalidRequest = -32600, + MethodNotFound = -32601, + InvalidParams = -32602, + InternalError = -32603, + serverErrorStart = -32099, + serverErrorEnd = -32000, + ServerNotInitialized = -32002, + UnknownErrorCode = -32001, + + // Defined by the protocol. + RequestCancelled = -32800, +}; + struct URI { std::string uri; std::string file;