From ccfe5d45573cf140a1587d45723340258f19e758 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sat, 6 Jan 2024 12:14:17 +0100 Subject: [PATCH 1/2] do not crash entire extension when analysis fails, instead report the error as a message but only every 15 minutes --- server/src/errorReporter.ts | 22 ++++++++++++++++++++++ server/src/server.ts | 19 +++++++++++++++++++ server/src/utils.ts | 13 ++++++++++--- 3 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 server/src/errorReporter.ts diff --git a/server/src/errorReporter.ts b/server/src/errorReporter.ts new file mode 100644 index 000000000..7bdb9fb11 --- /dev/null +++ b/server/src/errorReporter.ts @@ -0,0 +1,22 @@ +type cb = (msg: string) => void; + +let subscribers: Array = []; +const errorLastNotified: Record = {}; + +export const onErrorReported = (cb: (msg: string) => void) => { + subscribers.push(cb); + return () => { + subscribers = subscribers.filter((s) => s !== cb); + }; +}; + +export const reportError = (identifier: string, msg: string) => { + // Warn once per 15 min per error + if ( + errorLastNotified[identifier] == null || + errorLastNotified[identifier] < Date.now() - 15 * 1000 * 60 + ) { + errorLastNotified[identifier] = Date.now(); + subscribers.forEach((cb) => cb(msg)); + } +}; diff --git a/server/src/server.ts b/server/src/server.ts index a96953154..9cd7e68a8 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -25,6 +25,7 @@ import { fileURLToPath } from "url"; import { ChildProcess } from "child_process"; import { WorkspaceEdit } from "vscode-languageserver"; import { filesDiagnostics } from "./utils"; +import { onErrorReported } from "./errorReporter"; interface extensionConfiguration { allowBuiltInFormatter: boolean; @@ -1306,3 +1307,21 @@ function onMessage(msg: p.Message) { } } } + +// Gate behind a debug setting potentially? +onErrorReported((msg) => { + let params: p.ShowMessageParams = { + type: p.MessageType.Warning, + message: `ReScript tooling: Internal error. Something broke. Here's the error message that you can report if you want: + +${msg} + +(this message will only be reported once every 15 minutes)`, + }; + let message: p.NotificationMessage = { + jsonrpc: c.jsonrpcVersion, + method: "window/showMessage", + params: params, + }; + send(message); +}); diff --git a/server/src/utils.ts b/server/src/utils.ts index 0c3b27872..662c7ef99 100644 --- a/server/src/utils.ts +++ b/server/src/utils.ts @@ -12,6 +12,7 @@ import * as os from "os"; import * as codeActions from "./codeActions"; import * as c from "./constants"; import * as lookup from "./lookup"; +import { reportError } from "./errorReporter"; let tempFilePrefix = "rescript_format_file_" + process.pid + "_"; let tempFileId = 0; @@ -186,9 +187,15 @@ export let runAnalysisAfterSanityCheck = ( RESCRIPT_VERSION: rescriptVersion, }, }; - let stdout = childProcess.execFileSync(binaryPath, args, options); - - return JSON.parse(stdout.toString()); + try { + let stdout = childProcess.execFileSync(binaryPath, args, options); + return JSON.parse(stdout.toString()); + } catch (e) { + console.error(e); + // Element 0 is the action we're performing + reportError(String(args[0]), String(e)); + return null; + } }; export let runAnalysisCommand = ( From 94e74db96ec06766b55d782f7c5fdc08e2448ffa Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sat, 6 Jan 2024 12:17:22 +0100 Subject: [PATCH 2/2] changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f691f0c9..39723d8d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ ## master +- Better error recovery when analysis fails. https://github.com/rescript-lang/rescript-vscode/pull/880 + ## 1.32.0 - Expand type aliases in hovers. https://github.com/rescript-lang/rescript-vscode/pull/881