diff --git a/src/LanguageServerProtocol.fs b/src/LanguageServerProtocol.fs index 1953807..c35e7fe 100644 --- a/src/LanguageServerProtocol.fs +++ b/src/LanguageServerProtocol.fs @@ -12,6 +12,7 @@ module Server = open Newtonsoft.Json open Ionide.LanguageServerProtocol.JsonUtils open Newtonsoft.Json.Linq + open StreamJsonRpc let logger = LogProvider.getLoggerByName "LSP Server" @@ -77,23 +78,28 @@ module Server = | ErrorExitWithoutShutdown = 1 | ErrorStreamClosed = 2 + + /// The default RPC logic shipped with this library. All this does is mark LocalRpcExceptions as non-fatal + let defaultRpc (handler: IJsonRpcMessageHandler) = + { new JsonRpc(handler) with + member this.IsFatalException(ex: Exception) = + match ex with + | :? LocalRpcException -> false + | _ -> true } + let startWithSetup<'client when 'client :> Ionide.LanguageServerProtocol.ILspClient> (setupRequestHandlings: 'client -> Map) (input: Stream) (output: Stream) (clientCreator: (ClientNotificationSender * ClientRequestSender) -> 'client) + (customizeRpc: IJsonRpcMessageHandler -> JsonRpc) = use jsonRpcHandler = new HeaderDelimitedMessageHandler(output, input, jsonRpcFormatter) // Without overriding isFatalException, JsonRpc serializes exceptions and sends them to the client. // This is particularly bad for notifications such as textDocument/didChange which don't require a response, // and thus any exception that happens during e.g. text sync gets swallowed. - use jsonRpc = - { new JsonRpc(jsonRpcHandler) with - member this.IsFatalException(ex: Exception) = - match ex with - | :? LocalRpcException -> false - | _ -> true } + use jsonRpc = customizeRpc jsonRpcHandler /// When the server wants to send a notification to the client let sendServerNotification (rpcMethod: string) (notificationObj: obj) : AsyncLspResult =