From e17419c7cbf03c845b9a1d01767c668ce5e5aa1b Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Wed, 19 Jun 2024 14:59:07 +0200 Subject: [PATCH] CLI: Improve error message when fetching CLI version --- .../src/js-package-manager/NPMProxy.ts | 31 +++++++++++-------- .../src/js-package-manager/PNPMProxy.ts | 30 +++++++++++------- .../src/js-package-manager/Yarn1Proxy.ts | 24 ++++++++------ .../src/js-package-manager/Yarn2Proxy.ts | 21 ++++++++----- .../core-events/src/errors/server-errors.ts | 19 ++++++++++++ 5 files changed, 83 insertions(+), 42 deletions(-) diff --git a/code/lib/core-common/src/js-package-manager/NPMProxy.ts b/code/lib/core-common/src/js-package-manager/NPMProxy.ts index 8e996861f32a..bdb209d51f42 100644 --- a/code/lib/core-common/src/js-package-manager/NPMProxy.ts +++ b/code/lib/core-common/src/js-package-manager/NPMProxy.ts @@ -5,6 +5,8 @@ import { sync as findUpSync } from 'find-up'; import { existsSync, readFileSync } from 'fs'; import path from 'path'; import { logger } from '@storybook/node-logger'; +import { FindPackageVersionsError } from '@storybook/core-events/server-errors'; + import { JsPackageManager } from './JsPackageManager'; import type { PackageJson } from './PackageJson'; import type { InstallationMetadata, PackageMetadata } from './types'; @@ -225,23 +227,26 @@ export class NPMProxy extends JsPackageManager { fetchAllVersions: T ): Promise { const args = [fetchAllVersions ? 'versions' : 'version', '--json']; - - const commandResult = await this.executeCommand({ - command: 'npm', - args: ['info', packageName, ...args], - }); - try { + const commandResult = await this.executeCommand({ + command: 'npm', + args: ['info', packageName, ...args], + }); + const parsedOutput = JSON.parse(commandResult); - if (parsedOutput.error) { - // FIXME: improve error handling - throw new Error(parsedOutput.error.summary); - } else { - return parsedOutput; + if (parsedOutput.error?.summary) { + // this will be handled in the catch block below + throw parsedOutput.error.summary; } - } catch (e) { - throw new Error(`Unable to find versions of ${packageName} using npm`); + + return parsedOutput; + } catch (error) { + throw new FindPackageVersionsError({ + error, + packageManager: 'NPM', + packageName, + }); } } diff --git a/code/lib/core-common/src/js-package-manager/PNPMProxy.ts b/code/lib/core-common/src/js-package-manager/PNPMProxy.ts index a2f8baf6206b..df1bb5041a0d 100644 --- a/code/lib/core-common/src/js-package-manager/PNPMProxy.ts +++ b/code/lib/core-common/src/js-package-manager/PNPMProxy.ts @@ -3,6 +3,8 @@ import dedent from 'ts-dedent'; import { sync as findUpSync } from 'find-up'; import path from 'path'; import fs from 'fs'; +import { FindPackageVersionsError } from '@storybook/core-events/server-errors'; + import { JsPackageManager } from './JsPackageManager'; import type { PackageJson } from './PackageJson'; import type { InstallationMetadata, PackageMetadata } from './types'; @@ -222,22 +224,26 @@ export class PNPMProxy extends JsPackageManager { ): Promise { const args = [fetchAllVersions ? 'versions' : 'version', '--json']; - const commandResult = await this.executeCommand({ - command: 'pnpm', - args: ['info', packageName, ...args], - }); - try { + const commandResult = await this.executeCommand({ + command: 'pnpm', + args: ['info', packageName, ...args], + }); + const parsedOutput = JSON.parse(commandResult); - if (parsedOutput.error) { - // FIXME: improve error handling - throw new Error(parsedOutput.error.summary); - } else { - return parsedOutput; + if (parsedOutput.error?.summary) { + // this will be handled in the catch block below + throw parsedOutput.error.summary; } - } catch (e) { - throw new Error(`Unable to find versions of ${packageName} using pnpm`); + + return parsedOutput; + } catch (error) { + throw new FindPackageVersionsError({ + error, + packageManager: 'PNPM', + packageName, + }); } } diff --git a/code/lib/core-common/src/js-package-manager/Yarn1Proxy.ts b/code/lib/core-common/src/js-package-manager/Yarn1Proxy.ts index 5980b26accc4..6b6518d6858c 100644 --- a/code/lib/core-common/src/js-package-manager/Yarn1Proxy.ts +++ b/code/lib/core-common/src/js-package-manager/Yarn1Proxy.ts @@ -2,6 +2,8 @@ import dedent from 'ts-dedent'; import { sync as findUpSync } from 'find-up'; import { existsSync, readFileSync } from 'fs'; import path from 'path'; +import { FindPackageVersionsError } from '@storybook/core-events/server-errors'; + import { createLogStream } from '../utils/cli'; import { JsPackageManager } from './JsPackageManager'; import type { PackageJson } from './PackageJson'; @@ -162,20 +164,24 @@ export class Yarn1Proxy extends JsPackageManager { fetchAllVersions: T ): Promise { const args = [fetchAllVersions ? 'versions' : 'version', '--json']; - - const commandResult = await this.executeCommand({ - command: 'yarn', - args: ['info', packageName, ...args], - }); - try { + const commandResult = await this.executeCommand({ + command: 'yarn', + args: ['info', packageName, ...args], + }); + const parsedOutput = JSON.parse(commandResult); if (parsedOutput.type === 'inspect') { return parsedOutput.data; } - throw new Error(`Unable to find versions of ${packageName} using yarn`); - } catch (e) { - throw new Error(`Unable to find versions of ${packageName} using yarn`); + // eslint-disable-next-line local-rules/no-uncategorized-errors + throw new Error(`Yarn did not provide an output with type 'inspect'.`); + } catch (error) { + throw new FindPackageVersionsError({ + error, + packageManager: 'Yarn 1', + packageName, + }); } } diff --git a/code/lib/core-common/src/js-package-manager/Yarn2Proxy.ts b/code/lib/core-common/src/js-package-manager/Yarn2Proxy.ts index db4bb886c461..989e063256a5 100644 --- a/code/lib/core-common/src/js-package-manager/Yarn2Proxy.ts +++ b/code/lib/core-common/src/js-package-manager/Yarn2Proxy.ts @@ -4,6 +4,8 @@ import { existsSync, readFileSync } from 'fs'; import path from 'path'; import { PosixFS, VirtualFS, ZipOpenFS } from '@yarnpkg/fslib'; import { getLibzipSync } from '@yarnpkg/libzip'; +import { FindPackageVersionsError } from '@storybook/core-events/server-errors'; + import { createLogStream } from '../utils/cli'; import { JsPackageManager } from './JsPackageManager'; import type { PackageJson } from './PackageJson'; @@ -248,17 +250,20 @@ export class Yarn2Proxy extends JsPackageManager { ): Promise { const field = fetchAllVersions ? 'versions' : 'version'; const args = ['--fields', field, '--json']; - - const commandResult = await this.executeCommand({ - command: 'yarn', - args: ['npm', 'info', packageName, ...args], - }); - try { + const commandResult = await this.executeCommand({ + command: 'yarn', + args: ['npm', 'info', packageName, ...args], + }); + const parsedOutput = JSON.parse(commandResult); return parsedOutput[field]; - } catch (e) { - throw new Error(`Unable to find versions of ${packageName} using yarn 2`); + } catch (error) { + throw new FindPackageVersionsError({ + error, + packageManager: 'Yarn Berry', + packageName, + }); } } diff --git a/code/lib/core-events/src/errors/server-errors.ts b/code/lib/core-events/src/errors/server-errors.ts index e6719945d3f6..b85fcaa2783b 100644 --- a/code/lib/core-events/src/errors/server-errors.ts +++ b/code/lib/core-events/src/errors/server-errors.ts @@ -604,3 +604,22 @@ export class NoStatsForViteDevError extends StorybookError { `; } } + +export class FindPackageVersionsError extends StorybookError { + readonly category = Category.CLI; + + readonly code = 1; + + constructor( + public data: { error: Error | unknown; packageName: string; packageManager: string } + ) { + super(); + } + + template() { + return dedent` + Unable to find versions of "${this.data.packageName}" using ${this.data.packageManager} + ${this.data.error && `Reason: ${this.data.error}`} + `; + } +}