1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Display error dialog if extensions couldn't be loaded (#1752)

* Display error dialog if extensions couldn't be loaded
* Reject npm install on failure using the process exit code

Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com>
This commit is contained in:
Panu Horsmalahti 2020-12-14 09:23:59 +02:00 committed by GitHub
parent e408b0c6d9
commit 3300a99a78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 20 deletions

View File

@ -266,18 +266,30 @@ export class ExtensionDiscovery {
logger.info(`${logModule} loading extensions from ${extensionInstaller.extensionPackagesRoot}`); logger.info(`${logModule} loading extensions from ${extensionInstaller.extensionPackagesRoot}`);
if (fs.existsSync(path.join(extensionInstaller.extensionPackagesRoot, "package-lock.json"))) { // fs.remove won't throw if path is missing
await fs.remove(path.join(extensionInstaller.extensionPackagesRoot, "package-lock.json")); await fs.remove(path.join(extensionInstaller.extensionPackagesRoot, "package-lock.json"));
}
try { try {
// Verify write access to static/extensions, which is needed for symlinking
await fs.access(this.inTreeFolderPath, fs.constants.W_OK); await fs.access(this.inTreeFolderPath, fs.constants.W_OK);
// Set bundled folder path to static/extensions
this.bundledFolderPath = this.inTreeFolderPath; this.bundledFolderPath = this.inTreeFolderPath;
} catch { } catch {
// we need to copy in-tree extensions so that we can symlink them properly on "npm install" // If there is error accessing static/extensions, we need to copy in-tree extensions so that we can symlink them properly on "npm install".
// The error can happen if there is read-only rights to static/extensions, which would fail symlinking.
// Remove e.g. /Users/<username>/Library/Application Support/LensDev/extensions
await fs.remove(this.inTreeTargetPath); await fs.remove(this.inTreeTargetPath);
// Create folder e.g. /Users/<username>/Library/Application Support/LensDev/extensions
await fs.ensureDir(this.inTreeTargetPath); await fs.ensureDir(this.inTreeTargetPath);
// Copy static/extensions to e.g. /Users/<username>/Library/Application Support/LensDev/extensions
await fs.copy(this.inTreeFolderPath, this.inTreeTargetPath); await fs.copy(this.inTreeFolderPath, this.inTreeTargetPath);
// Set bundled folder path to e.g. /Users/<username>/Library/Application Support/LensDev/extensions
this.bundledFolderPath = this.inTreeTargetPath; this.bundledFolderPath = this.inTreeTargetPath;
} }

View File

@ -33,16 +33,26 @@ export class ExtensionInstaller {
installDependencies(): Promise<void> { installDependencies(): Promise<void> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
logger.info(`${logModule} installing dependencies at ${extensionPackagesRoot()}`); logger.info(`${logModule} installing dependencies at ${extensionPackagesRoot()}`);
const child = child_process.fork(this.npmPath, ["install", "--silent", "--no-audit", "--only=prod", "--prefer-offline", "--no-package-lock"], { const child = child_process.fork(this.npmPath, ["install", "--no-audit", "--only=prod", "--prefer-offline", "--no-package-lock"], {
cwd: extensionPackagesRoot(), cwd: extensionPackagesRoot(),
silent: true silent: true
}); });
let stderr = "";
child.on("close", () => { child.stderr.on("data", data => {
resolve(); stderr += String(data);
}); });
child.on("error", (err) => {
reject(err); child.on("close", (code) => {
if (code !== 0) {
reject(new Error(stderr));
} else {
resolve();
}
});
child.on("error", error => {
reject(error);
}); });
}); });
} }

View File

@ -93,8 +93,8 @@ app.on("ready", async () => {
// eslint-disable-next-line unused-imports/no-unused-vars-ts // eslint-disable-next-line unused-imports/no-unused-vars-ts
proxyServer = LensProxy.create(proxyPort, clusterManager); proxyServer = LensProxy.create(proxyPort, clusterManager);
} catch (error) { } catch (error) {
logger.error(`Could not start proxy (127.0.0:${proxyPort}): ${error.message}`); logger.error(`Could not start proxy (127.0.0:${proxyPort}): ${error?.message}`);
dialog.showErrorBox("Lens Error", `Could not start proxy (127.0.0:${proxyPort}): ${error.message || "unknown error"}`); dialog.showErrorBox("Lens Error", `Could not start proxy (127.0.0:${proxyPort}): ${error?.message || "unknown error"}`);
app.exit(); app.exit();
} }
@ -104,17 +104,21 @@ app.on("ready", async () => {
windowManager = WindowManager.getInstance<WindowManager>(proxyPort); windowManager = WindowManager.getInstance<WindowManager>(proxyPort);
// call after windowManager to see splash earlier // call after windowManager to see splash earlier
const extensions = await extensionDiscovery.load(); try {
const extensions = await extensionDiscovery.load();
// Subscribe to extensions that are copied or deleted to/from the extensions folder // Subscribe to extensions that are copied or deleted to/from the extensions folder
extensionDiscovery.events.on("add", (extension: InstalledExtension) => { extensionDiscovery.events.on("add", (extension: InstalledExtension) => {
extensionLoader.addExtension(extension); extensionLoader.addExtension(extension);
}); });
extensionDiscovery.events.on("remove", (lensExtensionId: LensExtensionId) => { extensionDiscovery.events.on("remove", (lensExtensionId: LensExtensionId) => {
extensionLoader.removeExtension(lensExtensionId); extensionLoader.removeExtension(lensExtensionId);
}); });
extensionLoader.initExtensions(extensions); extensionLoader.initExtensions(extensions);
} catch (error) {
dialog.showErrorBox("Lens Error", `Could not load extensions${error?.message ? `: ${error.message}` : ""}`);
}
setTimeout(() => { setTimeout(() => {
appEventBus.emit({ name: "service", action: "start" }); appEventBus.emit({ name: "service", action: "start" });