diff options
Diffstat (limited to 'editors/code/src/util.ts')
-rw-r--r-- | editors/code/src/util.ts | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts index 7a6657753..2f18f85a3 100644 --- a/editors/code/src/util.ts +++ b/editors/code/src/util.ts | |||
@@ -1,3 +1,6 @@ | |||
1 | import * as lc from "vscode-languageclient"; | ||
2 | import * as vscode from "vscode"; | ||
3 | |||
1 | let enabled: boolean = false; | 4 | let enabled: boolean = false; |
2 | 5 | ||
3 | export const log = { | 6 | export const log = { |
@@ -16,3 +19,40 @@ export const log = { | |||
16 | enabled = yes; | 19 | enabled = yes; |
17 | } | 20 | } |
18 | }; | 21 | }; |
22 | |||
23 | export async function sendRequestWithRetry<R>( | ||
24 | client: lc.LanguageClient, | ||
25 | method: string, | ||
26 | param: unknown, | ||
27 | token?: vscode.CancellationToken, | ||
28 | ): Promise<R> { | ||
29 | for (const delay of [2, 4, 6, 8, 10, null]) { | ||
30 | try { | ||
31 | return await (token | ||
32 | ? client.sendRequest(method, param, token) | ||
33 | : client.sendRequest(method, param) | ||
34 | ); | ||
35 | } catch (error) { | ||
36 | if (delay === null) { | ||
37 | log.error("LSP request timed out", { method, param, error }); | ||
38 | throw error; | ||
39 | } | ||
40 | |||
41 | if (error.code === lc.ErrorCodes.RequestCancelled) { | ||
42 | throw error; | ||
43 | } | ||
44 | |||
45 | if (error.code !== lc.ErrorCodes.ContentModified) { | ||
46 | log.error("LSP request failed", { method, param, error }); | ||
47 | throw error; | ||
48 | } | ||
49 | |||
50 | await sleep(10 * (1 << delay)); | ||
51 | } | ||
52 | } | ||
53 | throw 'unreachable'; | ||
54 | } | ||
55 | |||
56 | function sleep(ms: number) { | ||
57 | return new Promise(resolve => setTimeout(resolve, ms)); | ||
58 | } | ||