diff options
| author | Veetaha <gerzoh1@gmail.com> | 2020-02-22 20:58:00 +0200 |
|---|---|---|
| committer | Veetaha <gerzoh1@gmail.com> | 2020-02-23 15:49:09 +0200 |
| commit | 4cee7cddc84aa3769d5d3e87e5745f4c981bca28 (patch) | |
| tree | f8b98268925cf01e2cc74a9e12fac81a460c1eff /editors/code/src | |
| parent | 838ad6bcfb2a82c030e18d019b8a06752f0fc828 (diff) | |
| download | rust-4cee7cddc84aa3769d5d3e87e5745f4c981bca28.tar.gz rust-4cee7cddc84aa3769d5d3e87e5745f4c981bca28.zip | |
vscode: gracefully handle cancellation errors
Diffstat (limited to 'editors/code/src')
| -rw-r--r-- | editors/code/src/ctx.ts | 21 | ||||
| -rw-r--r-- | editors/code/src/highlighting.ts | 3 | ||||
| -rw-r--r-- | editors/code/src/inlay_hints.ts | 40 | ||||
| -rw-r--r-- | editors/code/src/util.ts | 40 |
4 files changed, 60 insertions, 44 deletions
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index dfc8aa7b9da..43540e0d8ea 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -52,24 +52,3 @@ export interface Disposable { dispose(): void; } export type Cmd = (...args: any[]) => unknown; - -export async function sendRequestWithRetry<R>( - client: lc.LanguageClient, - method: string, - param: unknown, - token?: vscode.CancellationToken, -): Promise<R> { - for (const delay of [2, 4, 6, 8, 10, null]) { - try { - return await (token ? client.sendRequest(method, param, token) : client.sendRequest(method, param)); - } catch (err) { - if (delay === null || err.code !== lc.ErrorCodes.ContentModified) { - throw err; - } - await sleep(10 * (1 << delay)); - } - } - throw 'unreachable'; -} - -const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts index b34e49c173a..77b4a1a68b8 100644 --- a/editors/code/src/highlighting.ts +++ b/editors/code/src/highlighting.ts @@ -3,7 +3,8 @@ import * as lc from 'vscode-languageclient'; import { ColorTheme, TextMateRuleSettings } from './color_theme'; -import { Ctx, sendRequestWithRetry } from './ctx'; +import { Ctx } from './ctx'; +import { sendRequestWithRetry } from './util'; export function activateHighlighting(ctx: Ctx) { const highlighter = new Highlighter(ctx); diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts index 7e6c310a9af..5f9229efbce 100644 --- a/editors/code/src/inlay_hints.ts +++ b/editors/code/src/inlay_hints.ts @@ -1,8 +1,8 @@ import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; -import { Ctx, sendRequestWithRetry } from './ctx'; -import { log } from './util'; +import { Ctx } from './ctx'; +import { log, sendRequestWithRetry } from './util'; export function activateInlayHints(ctx: Ctx) { const hintsUpdater = new HintsUpdater(ctx); @@ -152,28 +152,24 @@ class HintsUpdater { } private async queryHints(documentUri: string): Promise<InlayHint[] | null> { - const client = this.ctx.client; - if (!client) return null; + this.pending.get(documentUri)?.cancel(); - const request: InlayHintsParams = { - textDocument: { uri: documentUri }, - }; const tokenSource = new vscode.CancellationTokenSource(); - const prevHintsRequest = this.pending.get(documentUri); - prevHintsRequest?.cancel(); - this.pending.set(documentUri, tokenSource); - try { - return await sendRequestWithRetry<InlayHint[] | null>( - client, - 'rust-analyzer/inlayHints', - request, - tokenSource.token, - ); - } finally { - if (!tokenSource.token.isCancellationRequested) { - this.pending.delete(documentUri); - } - } + + const request: InlayHintsParams = { textDocument: { uri: documentUri } }; + + return sendRequestWithRetry<InlayHint[]>( + this.ctx.client, + 'rust-analyzer/inlayHints', + request, + tokenSource.token + ) + .catch(_ => null) + .finally(() => { + if (!tokenSource.token.isCancellationRequested) { + this.pending.delete(documentUri); + } + }); } } diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts index 7a6657753ba..2f18f85a392 100644 --- a/editors/code/src/util.ts +++ b/editors/code/src/util.ts @@ -1,3 +1,6 @@ +import * as lc from "vscode-languageclient"; +import * as vscode from "vscode"; + let enabled: boolean = false; export const log = { @@ -16,3 +19,40 @@ export const log = { enabled = yes; } }; + +export async function sendRequestWithRetry<R>( + client: lc.LanguageClient, + method: string, + param: unknown, + token?: vscode.CancellationToken, +): Promise<R> { + for (const delay of [2, 4, 6, 8, 10, null]) { + try { + return await (token + ? client.sendRequest(method, param, token) + : client.sendRequest(method, param) + ); + } catch (error) { + if (delay === null) { + log.error("LSP request timed out", { method, param, error }); + throw error; + } + + if (error.code === lc.ErrorCodes.RequestCancelled) { + throw error; + } + + if (error.code !== lc.ErrorCodes.ContentModified) { + log.error("LSP request failed", { method, param, error }); + throw error; + } + + await sleep(10 * (1 << delay)); + } + } + throw 'unreachable'; +} + +function sleep(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)); +} |
