Skip to content

Commit

Permalink
throw when mainConfig is missing or unable to be evaluated, also thro…
Browse files Browse the repository at this point in the history
…w when version is missing
  • Loading branch information
ndelangen committed Feb 16, 2024
1 parent c615357 commit 21945ad
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 51 deletions.
46 changes: 3 additions & 43 deletions code/lib/cli/src/upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { withTelemetry } from '@storybook/core-server';
import {
UpgradeStorybookToLowerVersionError,
UpgradeStorybookToSameVersionError,
UpgradeStorybookUnknownCurrentVersionError,
} from '@storybook/core-events/server-errors';

import chalk from 'chalk';
Expand Down Expand Up @@ -189,26 +190,11 @@ export const doUpgrade = async ({
);
const configDir = userSpecifiedConfigDir || inferredConfigDir || '.storybook';

let mainConfigLoadingError = '';

const mainConfig = await loadMainConfig({ configDir }).catch((err) => {
mainConfigLoadingError = String(err);
return false;
});
const mainConfig = await loadMainConfig({ configDir });

// GUARDS
if (!storybookVersion) {
logger.info(missingStorybookVersionMessage());
results = { preCheckFailure: PreCheckFailure.UNDETECTED_SB_VERSION };
} else if (
typeof mainConfigPath === 'undefined' ||
mainConfigLoadingError.includes('No configuration files have been found')
) {
logger.info(mainjsNotFoundMessage(configDir));
results = { preCheckFailure: PreCheckFailure.MAINJS_NOT_FOUND };
} else if (typeof mainConfig === 'boolean') {
logger.info(mainjsExecutionFailureMessage(mainConfigPath, mainConfigLoadingError));
results = { preCheckFailure: PreCheckFailure.MAINJS_EVALUATION };
throw new UpgradeStorybookUnknownCurrentVersionError();
}

// BLOCKERS
Expand Down Expand Up @@ -293,32 +279,6 @@ export const doUpgrade = async ({
}
};

function missingStorybookVersionMessage(): string {
return dedent`
[Storybook automigrate] ❌ Unable to determine Storybook version so that the automigrations will be skipped.
🤔 Are you running automigrate from your project directory? Please specify your Storybook config directory with the --config-dir flag.
`;
}

function mainjsExecutionFailureMessage(
mainConfigPath: string,
mainConfigLoadingError: string
): string {
return dedent`
[Storybook automigrate] ❌ Failed trying to evaluate ${chalk.blue(
mainConfigPath
)} with the following error: ${mainConfigLoadingError}
Please fix the error and try again.
`;
}

function mainjsNotFoundMessage(configDir: string): string {
return dedent`[Storybook automigrate] Could not find or evaluate your Storybook main.js config directory at ${chalk.blue(
configDir
)} so the automigrations will be skipped. You might be running this command in a monorepo or a non-standard project structure. If that is the case, please rerun this command by specifying the path to your Storybook config directory via the --config-dir option.`;
}

export async function upgrade(options: UpgradeOptions): Promise<void> {
await withTelemetry('upgrade', { cliOptions: options }, () => doUpgrade(options));
}
12 changes: 9 additions & 3 deletions code/lib/core-common/src/utils/load-main-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import type { StorybookConfig } from '@storybook/types';
import { serverRequire, serverResolve } from './interpret-require';
import { validateConfigurationFiles } from './validate-configuration-files';
import { readFile } from 'fs/promises';
import { MainFileESMOnlyImportError } from '@storybook/core-events/server-errors';
import {
MainFileESMOnlyImportError,
MainFileFailedEvaluationError,
} from '@storybook/core-events/server-errors';

export async function loadMainConfig({
configDir = '.storybook',
Expand Down Expand Up @@ -50,7 +53,10 @@ export async function loadMainConfig({

throw out;
}
throw e;
//

throw new MainFileFailedEvaluationError({
location: relative(process.cwd(), mainJsPath),
error: e,
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import slash from 'slash';
import { once } from '@storybook/node-logger';

import { boost } from './interpret-files';
import { MainFileMissingError } from '@storybook/core-events/server-errors';

export async function validateConfigurationFiles(configDir: string) {
const extensionsPattern = `{${Array.from(boost).join(',')}}`;
Expand All @@ -20,9 +21,6 @@ export async function validateConfigurationFiles(configDir: string) {
}

if (!mainConfigPath) {
throw new Error(dedent`
No configuration files have been found in your configDir (${path.resolve(configDir)}).
Storybook needs "main.js" file, please add it (or pass a custom config dir flag to Storybook to tell where your main.js file is located at).
`);
throw new MainFileMissingError({ location: configDir });
}
}
61 changes: 60 additions & 1 deletion code/lib/core-events/src/errors/server-errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,9 @@ export class MainFileESMOnlyImportError extends StorybookError {

readonly code = 5;

public documentation =
'https://github.com/storybookjs/storybook/issues/23972#issuecomment-1948534058';

constructor(
public data: { location: string; line: string | undefined; num: number | undefined }
) {
Expand Down Expand Up @@ -428,14 +431,55 @@ export class MainFileESMOnlyImportError extends StorybookError {

message.push(
'',
white(`Convert the dynamic import to an dynamic import where they are used.`),
white(`Convert the static import to an dynamic import where they are used.`),
white(`Example:`) + ' ' + gray(`await import(<your ESM only module>);`)
);

return message.join('\n');
}
}

export class MainFileMissingError extends StorybookError {
readonly category = Category.CORE_SERVER;

readonly code = 6;

public readonly documentation = 'https://storybook.js.org/docs/configure';

constructor(public data: { location: string }) {
super();
}

template() {
return dedent`
No configuration files have been found in your configDir: ${yellow(this.data.location)}.
Storybook needs "main.js" file, please add it.
You can pass a --config-dir flag to tell Storybook, where your main.js file is located at).
`;
}
}

export class MainFileFailedEvaluationError extends StorybookError {
readonly category = Category.CORE_SERVER;

readonly code = 7;

public readonly documentation = 'https://storybook.js.org/docs/configure';

constructor(public data: { location: string; error: Error }) {
super();
}

template() {
return dedent`
Storybook couldn't evaluate your ${yellow(this.data.location)} file.
${this.data.error.message}
`;
}
}

export class GenerateNewProjectOnInitError extends StorybookError {
readonly category = Category.CLI_INIT;

Expand Down Expand Up @@ -510,3 +554,18 @@ export class UpgradeStorybookToSameVersionError extends StorybookError {
`;
}
}

export class UpgradeStorybookUnknownCurrentVersionError extends StorybookError {
readonly category = Category.CLI_UPGRADE;

readonly code = 5;

template() {
return dedent`
We couldn't determine the current version of Storybook in your project.
Are you running the storybook CLI in a project without Storybook?
It might help if you specify your Storybook config directory with the --config-dir flag.
`;
}
}

0 comments on commit 21945ad

Please sign in to comment.