Skip to content

Commit a014ba8

Browse files
authored
Handle non-async exceptions from LSP handlers (#25)
* Revert "Always run server handlers inside an `async` context" This reverts commit 5e00d67. * Handle non-async exceptions from LSP handlers
1 parent cb72ed5 commit a014ba8

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

src/LanguageServerProtocol.fs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,21 @@ module Server =
159159

160160
let requestHandling<'param, 'result> (run: 'param -> AsyncLspResult<'result>) : Delegate =
161161
let runAsTask param ct =
162+
let asyncLspResult =
163+
try
164+
// Although `run` returns an async result, its body may not be fully in an async context.
165+
// Here we make sure that we catch and properly handle any exception before the first async.
166+
run param
167+
with
168+
| ex ->
169+
let rpcException = LocalRpcException(ex.Message)
170+
rpcException.ErrorCode <- JsonRpc.ErrorCodes.internalError
171+
rpcException.ErrorData <- ex.Data
172+
raise rpcException
173+
162174
let asyncContinuation =
163175
async {
164-
// Make sure we call `run` inside an `async` block.
165-
// Although, `run` returns an Async<...> value, it's body doesn't *have* to be all async,
166-
// so any exceptions raised in non-async part can bubble up and kill a thread.
167-
// Calling `run` inside an `async` block ensures that any raised exceptions will be caught and
168-
// sent back in a response to an LSP client.
169-
let! lspResult = run param
176+
let! lspResult = asyncLspResult
170177

171178
return
172179
match lspResult with

0 commit comments

Comments
 (0)