From 36c480699f2fc252d8360be608f6e0e9bc100bc3 Mon Sep 17 00:00:00 2001 From: Aasim Khan Date: Fri, 3 Jun 2022 19:41:09 -0700 Subject: [PATCH] Surfacing extension install errors (#19613) * Surfacing extension install error * Fixing error property * removing unncessary await * Fixing error type and message * Fixing some more strings * Adding missing period * Consolidating some strings * consolidating strings * revert vbump * Switching to ExtensionManagementError --- src/sql/base/common/locConstants.ts | 2 +- .../node/extensionManagementService.ts | 6 ++++-- .../extensions/browser/extensions.contribution.ts | 5 ++++- .../extensions/browser/extensionsWorkbenchService.ts | 9 +++++---- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/sql/base/common/locConstants.ts b/src/sql/base/common/locConstants.ts index 52de8514f5..d1f3480363 100644 --- a/src/sql/base/common/locConstants.ts +++ b/src/sql/base/common/locConstants.ts @@ -34,7 +34,7 @@ export function extensionsActionsInstallExtensionCompletedAndReloadRequired(exte export function extensionsActionsReinstallActionSuccessReload(extension: string): string { return localize('ReinstallAction.successReload', "Please reload Azure Data Studio to complete reinstalling the extension {0}.", extension); } export const extensionsViewletRecommendedExtensions = localize('recommendedExtensions', "Marketplace"); export const extensionsViewsScenarioTypeUndefined = localize('scenarioTypeUndefined', 'The scenario type for extension recommendations must be provided.'); -export function extensionsWorkbenchServiceIncompatible(extension: string, version: string) { return localize('incompatible', "Unable to install extension '{0}' as it is not compatible with Azure Data Studio '{1}'.", extension, version); } +export function extensionsWorkbenchServiceIncompatible(extension: string, extensionVersion: string, currentAzDataVersion: string, requiredAzDataVersion: string) { return localize('incompatible', "Unable to install version '{0}' of extension '{1}' as it is not compatible with Azure Data Studio '{2}'. Update to Azure Data Studio {3} to install the extension.", extensionVersion, extension, currentAzDataVersion, requiredAzDataVersion); } export const fileActionsContributionNewQuery = localize('newQuery', "New Query"); export const fileActionsContributionMiNewQuery = localize({ key: 'miNewQuery', comment: ['&& denotes a mnemonic'] }, "New &&Query"); export const fileActionsContributionMiNewNotebook = localize({ key: 'miNewNotebook', comment: ['&& denotes a mnemonic'] }, "&&New Notebook"); diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 903f30d271..53331a7ad6 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -3,6 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { extensionsWorkbenchServiceIncompatible } from 'sql/base/common/locConstants'; import { CancellationToken } from 'vs/base/common/cancellation'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { Schemas } from 'vs/base/common/network'; @@ -20,7 +21,8 @@ import { INativeEnvironmentService } from 'vs/platform/environment/common/enviro import { AbstractExtensionManagementService, AbstractExtensionTask, IInstallExtensionTask, INSTALL_ERROR_VALIDATING, IUninstallExtensionTask, joinErrors, UninstallExtensionTaskOptions } from 'vs/platform/extensionManagement/common/abstractExtensionManagementService'; import { ExtensionManagementError, IExtensionGalleryService, IExtensionIdentifier, IExtensionManagementService, IGalleryExtension, IGalleryMetadata, ILocalExtension, InstallOperation, InstallOptions, - InstallVSIXOptions + InstallVSIXOptions, + INSTALL_ERROR_INCOMPATIBLE } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions, ExtensionIdentifierWithVersion, getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ExtensionsDownloader } from 'vs/platform/extensionManagement/node/extensionDownloader'; @@ -114,7 +116,7 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi throw new Error(nls.localize('incompatible', "Unable to install extension '{0}' as it is not compatible with the current VS Code engine version '{1}'.", id, product.vscodeVersion)); } if (manifest.engines?.azdata && !isEngineValid(manifest.engines.azdata, product.version, product.date)) { - throw new Error(nls.localize('incompatibleAzdata', "Unable to install extension '{0}' as it is not compatible with Azure Data Studio '{1}'.", id, product.version)); + throw new ExtensionManagementError(extensionsWorkbenchServiceIncompatible(id, manifest.version, product.version, manifest.engines.azdata), INSTALL_ERROR_INCOMPATIBLE); } /* if (manifest.engines && manifest.engines.vscode && !isEngineValid(manifest.engines.vscode, product.version, product.date)) { diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index 1547fe7b54..93dcf6fe29 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -760,7 +760,10 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi openLabel: mnemonicButtonLabel(localize({ key: 'installButton', comment: ['&& denotes a mnemonic'] }, "&&Install")) }); if (vsixPaths) { - await commandService.executeCommand(INSTALL_EXTENSION_FROM_VSIX_COMMAND_ID, vsixPaths); + // {{SQL CARBON EDIT}} - Adding error handling + commandService.executeCommand(INSTALL_EXTENSION_FROM_VSIX_COMMAND_ID, vsixPaths).catch(e => { + notificationService.error(e); + }); } } }); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index 54153a96c5..775a5b289a 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -14,7 +14,7 @@ import { IPager, mapPager, singlePagePager } from 'vs/base/common/paging'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions, - InstallExtensionEvent, DidUninstallExtensionEvent, IExtensionIdentifier, InstallOperation, DefaultIconPath, InstallOptions, WEB_EXTENSION_TAG, InstallExtensionResult + InstallExtensionEvent, DidUninstallExtensionEvent, IExtensionIdentifier, InstallOperation, DefaultIconPath, InstallOptions, WEB_EXTENSION_TAG, InstallExtensionResult, INSTALL_ERROR_INCOMPATIBLE, ExtensionManagementError } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IWorkbenchExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, areSameExtensions, getMaliciousExtensionsSet, groupByExtension, ExtensionIdentifierWithVersion, getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; @@ -1042,7 +1042,8 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension // The check is added here because we want to fail fast instead of downloading the VSIX and then fail. if (gallery.properties.engine && (!isEngineValid(gallery.properties.engine, this.productService.vscodeVersion, this.productService.date) || (gallery.properties.azDataEngine && !isEngineValid(gallery.properties.azDataEngine, this.productService.version, this.productService.date)))) { - return Promise.reject(new Error(nls.localize('incompatible2', "Unable to install version '{2}' of extension '{0}' as it is not compatible with Azure Data Studio '{1}'.", extension.gallery!.identifier.id, this.productService.version, gallery.version))); + const error = new ExtensionManagementError(locConstants.extensionsWorkbenchServiceIncompatible(extension.gallery!.identifier.id, gallery.version, this.productService.version, gallery.properties.azDataEngine), INSTALL_ERROR_INCOMPATIBLE); + return Promise.reject(error); } return this.installWithProgress(async () => { @@ -1098,9 +1099,9 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension } return this.galleryService.getCompatibleExtension(extension.gallery.identifier, version) - .then(gallery => { + .then(async (gallery) => { if (!gallery) { - return Promise.reject(new Error(locConstants.extensionsWorkbenchServiceIncompatible(extension.gallery!.identifier.id, version))); // {{SQL CARBON EDIT}} Change vscode to ads + throw new ExtensionManagementError(locConstants.extensionsWorkbenchServiceIncompatible(extension.gallery!.identifier.id, extension.gallery.version, version, (await extension.getManifest(undefined)).engines.azdata), INSTALL_ERROR_INCOMPATIBLE); // {{SQL CARBON EDIT}} Change vscode to ads } return this.installWithProgress(async () => { const installed = await this.installFromGallery(extension, gallery);