From ca0f32f8fb0d813969ad56f4b5a3ff67e0f8ef91 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sun, 24 Mar 2024 22:46:24 +0100 Subject: [PATCH] (#248) LSP: more robust service calls, log more errors --- .../lang/lsp/ide/LSPRequestManager.kt | 41 +++++++++---------- .../languagehost/TextDocumentServiceQueue.kt | 30 +++++++------- 2 files changed, 34 insertions(+), 37 deletions(-) diff --git a/src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/ide/LSPRequestManager.kt b/src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/ide/LSPRequestManager.kt index fa5073f0..218555fb 100644 --- a/src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/ide/LSPRequestManager.kt +++ b/src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/ide/LSPRequestManager.kt @@ -3,6 +3,7 @@ */ package com.intellij.plugin.powershell.lang.lsp.ide +import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.diagnostic.thisLogger import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.plugin.powershell.lang.lsp.languagehost.LanguageServerEndpoint @@ -22,42 +23,36 @@ class LSPRequestManager( private fun checkStatus(): Boolean = serverEndpoint.isRunning suspend fun didClose(params: DidCloseTextDocumentParams) { - if (checkStatus()) { - handleServerError { - if (documentSyncOptions == null || documentSyncOptions.openClose) queue.didClose(params) - } + serviceCall { + if (documentSyncOptions == null || documentSyncOptions.openClose) queue.didClose(params) } } suspend fun didOpen(params: DidOpenTextDocumentParams) { - if (checkStatus()) { - handleServerError { - if (documentSyncOptions == null || documentSyncOptions.openClose) queue.didOpen(params) - } + serviceCall { + if (documentSyncOptions == null || documentSyncOptions.openClose) queue.didOpen(params) } } suspend fun didChange(params: DidChangeTextDocumentParams) { - if (checkStatus()) { - handleServerError { - if (documentSyncOptions == null || documentSyncOptions.change != null) queue.didChange(params) - } + serviceCall { + if (documentSyncOptions == null || documentSyncOptions.change != null) queue.didChange(params) } } - suspend fun completion(params: CompletionParams): Either, CompletionList>? { - if (checkStatus()) { - return handleServerError { - if (capabilities.completionProvider != null) - queue.completion(params) - else null - } + suspend fun completion(params: CompletionParams): Either, CompletionList>? = + serviceCall { + if (capabilities.completionProvider != null) + queue.completion(params) + else null } - return null - } + private suspend fun serviceCall(action: suspend () -> T): T? { + if (!checkStatus()) { + logger.error("ServerEndpoint does not report isRunning == true") + return null + } - private suspend fun handleServerError(action: suspend () -> T): T? { try { return action() } catch (e: Throwable) { @@ -71,3 +66,5 @@ class LSPRequestManager( } } } + +private val logger = logger() diff --git a/src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/languagehost/TextDocumentServiceQueue.kt b/src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/languagehost/TextDocumentServiceQueue.kt index 764098b3..d7f0d0d1 100644 --- a/src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/languagehost/TextDocumentServiceQueue.kt +++ b/src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/languagehost/TextDocumentServiceQueue.kt @@ -15,11 +15,8 @@ private val logger = logger() class TextDocumentServiceQueue(private val textDocumentService: () -> TextDocumentService?) { - private val service: TextDocumentService? - get() = textDocumentService() - private val mutex = Mutex() - private suspend fun executeTask(id: String, logDescription: Any? = null, task: suspend () -> T): T { + private suspend fun executeTask(id: String, logDescription: Any? = null, task: suspend (TextDocumentService) -> T): T? { logger.trace { val summary = "$id: operation queued." val description = logDescription?.toString() @@ -32,7 +29,10 @@ class TextDocumentServiceQueue(private val textDocumentService: () -> TextDocume withContext(Dispatchers.IO) { logger.trace { "$id: executing on the IO context." } try { - task() + textDocumentService()?.let { task(it) } ?: run { + logger.error("Cannot get the service to perform task $id.") + null + } } finally { logger.trace { "$id: finished." } } @@ -41,31 +41,31 @@ class TextDocumentServiceQueue(private val textDocumentService: () -> TextDocume } suspend fun didOpen(params: DidOpenTextDocumentParams) { - executeTask("didOpen notification", params) { - service?.didOpen(params) + executeTask("didOpen notification", params) { service -> + service.didOpen(params) } } suspend fun didClose(params: DidCloseTextDocumentParams) { - executeTask("didClose notification", params) { - service?.didClose(params) + executeTask("didClose notification", params) { service -> + service.didClose(params) } } suspend fun didSave(params: DidSaveTextDocumentParams) { - executeTask("didSave notification", params) { - service?.didSave(params) + executeTask("didSave notification", params) { service -> + service.didSave(params) } } suspend fun didChange(params: DidChangeTextDocumentParams) { - executeTask("didChange notification", params) { - service?.didChange(params) + executeTask("didChange notification", params) { service -> + service.didChange(params) } } suspend fun completion(params: CompletionParams): Either, CompletionList>? = - executeTask("completion request", params) { - service?.completion(params)?.await() + executeTask("completion request", params) { service -> + service.completion(params)?.await() } }