From 715a8509fbff04ea2af0db30b236f07a8a7e8a1b Mon Sep 17 00:00:00 2001 From: Akos Kitta Date: Wed, 10 May 2023 14:06:15 +0200 Subject: [PATCH] fix: show notification if lib/core install failed Closes #621 Signed-off-by: Akos Kitta --- .../filterable-list-container.tsx | 28 ++++++++++++++---- .../src/common/protocol/installable.ts | 29 ++++++++++++++++++- .../src/node/boards-service-impl.ts | 3 +- .../src/node/library-service-impl.ts | 17 +++++++---- i18n/en.json | 4 +++ 5 files changed, 69 insertions(+), 12 deletions(-) diff --git a/arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx b/arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx index bf7eec3cf..ae90068a7 100644 --- a/arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx +++ b/arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx @@ -6,13 +6,20 @@ import { MessageService } from '@theia/core/lib/common/message-service'; import { ConfirmDialog } from '@theia/core/lib/browser/dialogs'; import { Searchable } from '../../../common/protocol/searchable'; import { ExecuteWithProgress } from '../../../common/protocol/progressible'; -import { Installable } from '../../../common/protocol/installable'; +import { + Installable, + libraryInstallFailed, + platformInstallFailed, +} from '../../../common/protocol/installable'; import { ArduinoComponent } from '../../../common/protocol/arduino-component'; import { SearchBar } from './search-bar'; import { ListWidget } from './list-widget'; import { ComponentList } from './component-list'; import { ListItemRenderer } from './list-item-renderer'; -import { ResponseServiceClient } from '../../../common/protocol'; +import { + LibraryPackage, + ResponseServiceClient, +} from '../../../common/protocol'; import { nls } from '@theia/core/lib/common'; import { FilterRenderer } from './filter-renderer'; import { DisposableCollection } from '@theia/core/lib/common/disposable'; @@ -130,13 +137,24 @@ export class FilterableListContainer< } private async install(item: T, version: Installable.Version): Promise { - const { install, searchable } = this.props; + const { install, searchable, messageService } = this.props; + const { name } = item; await ExecuteWithProgress.doWithProgress({ ...this.props, progressText: nls.localize('arduino/common/processing', 'Processing') + - ` ${item.name}:${version}`, - run: ({ progressId }) => install({ item, progressId, version }), + ` ${name}:${version}`, + run: async ({ progressId }) => { + try { + await install({ item, progressId, version }); + } catch (err) { + const message = LibraryPackage.is(item) // TODO: this dispatch does not belong here + ? libraryInstallFailed(name, version) + : platformInstallFailed(name, version); + const cause = err instanceof Error ? err.message : String(err); + messageService.error(`${message} ${cause}`); + } + }, }); const items = await searchable.search(this.state.searchOptions); this.setState({ items, edited: undefined }); diff --git a/arduino-ide-extension/src/common/protocol/installable.ts b/arduino-ide-extension/src/common/protocol/installable.ts index 2b05cf819..a7c70f891 100644 --- a/arduino-ide-extension/src/common/protocol/installable.ts +++ b/arduino-ide-extension/src/common/protocol/installable.ts @@ -1,4 +1,5 @@ import type { MessageService } from '@theia/core/lib/common/message-service'; +import { nls } from '@theia/core/lib/common/nls'; import { coerce as coerceSemver, compare as compareSemver, @@ -9,6 +10,32 @@ import type { ArduinoComponent } from './arduino-component'; import { ExecuteWithProgress } from './progressible'; import type { ResponseServiceClient } from './response-service'; +export function libraryInstallFailed( + name: string, + version?: string | undefined +): string { + const versionSuffix = version ? `:${version}` : ''; + return nls.localize( + 'arduino/installable/libraryInstallFailed', + "Failed to install library: '{0}{1}'.", + name, + versionSuffix + ); +} + +export function platformInstallFailed( + name: string, + version?: string | undefined +): string { + const versionSuffix = version ? `:${version}` : ''; + return nls.localize( + 'arduino/installable/platformInstallFailed', + "Failed to install platform: '{0}{1}'.", + name, + versionSuffix + ); +} + export interface Installable { /** * If `options.version` is specified, that will be installed. Otherwise, `item.availableVersions[0]`. @@ -62,7 +89,7 @@ export namespace Installable { 'remove', 'unknown', ] as const; - export type Action = typeof ActionLiterals[number]; + export type Action = (typeof ActionLiterals)[number]; export function action(params: { installed?: Version | undefined; diff --git a/arduino-ide-extension/src/node/boards-service-impl.ts b/arduino-ide-extension/src/node/boards-service-impl.ts index b336d04c4..e04aa909f 100644 --- a/arduino-ide-extension/src/node/boards-service-impl.ts +++ b/arduino-ide-extension/src/node/boards-service-impl.ts @@ -18,6 +18,7 @@ import { BoardSearch, sortComponents, SortGroup, + platformInstallFailed, } from '../common/protocol'; import { PlatformInstallRequest, @@ -474,7 +475,7 @@ export class BoardsServiceImpl }); resp.on('error', (error) => { this.responseService.appendToOutput({ - chunk: `Failed to install platform: ${item.id}.\n`, + chunk: `${platformInstallFailed(item.id, version)}\n`, }); this.responseService.appendToOutput({ chunk: `${error.toString()}\n`, diff --git a/arduino-ide-extension/src/node/library-service-impl.ts b/arduino-ide-extension/src/node/library-service-impl.ts index e31020995..afdfae052 100644 --- a/arduino-ide-extension/src/node/library-service-impl.ts +++ b/arduino-ide-extension/src/node/library-service-impl.ts @@ -8,7 +8,10 @@ import { sortComponents, SortGroup, } from '../common/protocol'; -import { Installable } from '../common/protocol/installable'; +import { + Installable, + libraryInstallFailed, +} from '../common/protocol/installable'; import { LibraryDependency, LibraryLocation, @@ -34,6 +37,7 @@ import { } from './cli-protocol/cc/arduino/cli/commands/v1/lib_pb'; import { CoreClientAware } from './core-client-provider'; import { ExecuteWithProgress } from './grpc-progressible'; +import { ServiceError } from './service-error'; @injectable() export class LibraryServiceImpl @@ -272,7 +276,12 @@ export class LibraryServiceImpl (resolve, reject) => { client.libraryResolveDependencies(req, (error, resp) => { if (error) { - reject(error); + console.error('Failed to list library dependencies', error); + // If a gRPC service error, it removes the code and the number to provider more readable error message to the user. + const unwrappedError = ServiceError.is(error) + ? new Error(error.details) + : error; + reject(unwrappedError); return; } resolve( @@ -344,9 +353,7 @@ export class LibraryServiceImpl }); resp.on('error', (error) => { this.responseService.appendToOutput({ - chunk: `Failed to install library: ${item.name}${ - version ? `:${version}` : '' - }.\n`, + chunk: `${libraryInstallFailed(item.name, version)}\n`, }); this.responseService.appendToOutput({ chunk: `${error.toString()}\n`, diff --git a/i18n/en.json b/i18n/en.json index d58f478f6..ecd94c757 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -278,6 +278,10 @@ "updateAvailable": "Update Available", "versionDownloaded": "Arduino IDE {0} has been downloaded." }, + "installable": { + "libraryInstallFailed": "Failed to install library: '{0}{1}'.", + "platformInstallFailed": "Failed to install platform: '{0}{1}'." + }, "library": { "addZip": "Add .ZIP Library...", "arduinoLibraries": "Arduino libraries",