From 6b0a9f745bac205b63addfd8792ddade9e76c1bd Mon Sep 17 00:00:00 2001 From: Ryan Vandersmith Date: Thu, 12 Jan 2023 15:04:59 -0700 Subject: [PATCH] Improve error handling for MOPS and Vessel integrations (#149) * Resolve 'ic-mops' npm package instead of global 'mops' binary * Improve error handling for missing MOPS or Vessel installation * Detect global 'ic-mops' * 0.7.3 * Clarify possible MOPS installation locations in error message * Use more detailed error message for Vessel sources * Automatically retry package configuration on file change * Run 'sources' command asynchronously * 0.7.4 --- package-lock.json | 4 ++-- package.json | 2 +- src/server/server.ts | 31 ++++++++++++++++++++----------- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index b36a37fa..1a302942 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-motoko", - "version": "0.7.3", + "version": "0.7.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-motoko", - "version": "0.7.3", + "version": "0.7.4", "dependencies": { "change-case": "4.1.2", "fast-glob": "3.2.12", diff --git a/package.json b/package.json index 8016396a..408203be 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "vscode-motoko", "displayName": "Motoko", "description": "Motoko language support", - "version": "0.7.3", + "version": "0.7.4", "publisher": "dfinity-foundation", "repository": "https://github.com/dfinity/vscode-motoko", "engines": { diff --git a/src/server/server.ts b/src/server/server.ts index a90a749f..6201b45e 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -1,4 +1,4 @@ -import { execSync } from 'child_process'; +import { exec } from 'child_process'; import * as glob from 'fast-glob'; import { existsSync, readFileSync } from 'fs'; import { Node } from 'motoko/lib/ast'; @@ -39,6 +39,7 @@ import { resetContexts, } from './context'; import DfxResolver from './dfx'; +import { organizeImports } from './imports'; import { getAstInformation } from './information'; import { findDefinition, @@ -46,7 +47,6 @@ import { locationFromDefinition, rangeFromNode, } from './navigation'; -import { vesselSources } from './rust'; import { Program, asNode, findNodes } from './syntax'; import { formatMotoko, @@ -54,7 +54,6 @@ import { resolveFilePath, resolveVirtualPath, } from './utils'; -import { organizeImports } from './imports'; interface Settings { motoko: MotokoSettings; @@ -74,11 +73,14 @@ const ignoreGlobs = [ async function getPackageSources( directory: string, ): Promise<[string, string][]> { - function sourcesFromCommand(command: string) { + async function sourcesFromCommand(command: string) { console.log(`Running \`${command}\` in directory: ${directory}`); - const result = execSync(command, { - cwd: directory, - }).toString('utf8'); + const result = await new Promise((resolve, reject) => + exec(command, { cwd: directory }, (err, stdout) => + // @ts-ignore + err ? reject(err) : resolve(stdout.toString('utf8')), + ), + ); const args = result.split(/\s/); // TODO: account for quoted strings console.log('Received:', args); if (!args) { @@ -136,24 +138,26 @@ async function getPackageSources( try { return sourcesFromCommand(command); } catch (err: any) { - console.error( + throw new Error( `Error while running \`${command}\`.\nMake sure Vessel is installed (https://github.com/dfinity/vessel/#getting-started).\n${ err?.message || err }`, ); - return vesselSources(directory); + // return vesselSources(directory); } } else { return []; } } -let packageConfigChangeTimeout: ReturnType; let loadingPackages = false; +let packageConfigError = false; +let packageConfigChangeTimeout: ReturnType; function notifyPackageConfigChange() { clearTimeout(packageConfigChangeTimeout); loadingPackages = true; setTimeout(async () => { + packageConfigError = false; try { resetContexts(); @@ -214,12 +218,13 @@ function notifyPackageConfigChange() { }, ); } catch (err) { - // context.error = `unable to load project dependencies: ${err}`; + packageConfigError = true; context.error = String(err); console.warn(err); return; } } catch (err) { + packageConfigError = true; console.error( `Error while configuring Vessel directory (${dir}): ${err}`, ); @@ -239,6 +244,7 @@ function notifyPackageConfigChange() { notifyWorkspace(); // Update virtual file system notifyDfxChange(); // Reload dfx.json } catch (err) { + packageConfigError = true; loadingPackages = false; console.error(`Error while loading packages: ${err}`); } @@ -1150,6 +1156,9 @@ connection.onReferences( let validatingTimeout: ReturnType; let validatingUri: string | undefined; documents.onDidChangeContent((event) => { + if (packageConfigError) { + notifyPackageConfigChange(); + } const document = event.document; const { uri } = document; if (uri === validatingUri) {