Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core: Unify error when builder is missing #24177

Merged
merged 1 commit into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions code/lib/core-events/src/errors/server-errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,25 @@ export class CriticalPresetLoadError extends StorybookError {
`;
}
}

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

readonly code = 3;

public readonly documentation = 'https://github.com/storybookjs/storybook/issues/24071';

template() {
return dedent`
Storybook could not find a builder configuration for your project.
Builders normally come from a framework package e.g. '@storybook/react-vite', or from builder packages e.g. '@storybook/builder-vite'.

- Does your main config file contain a 'framework' field configured correctly?
- Is the Storybook framework package installed correctly?
- If you don't use a framework, does your main config contain a 'core.builder' configured correctly?
- Are you in a monorepo and perhaps the framework package is hoisted incorrectly?

If you believe this is a bug, please describe your issue in detail on Github.
`;
}
}
5 changes: 4 additions & 1 deletion code/lib/core-server/src/build-dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { global } from '@storybook/global';
import { telemetry } from '@storybook/telemetry';

import { join, resolve } from 'path';
import { MissingBuilderError } from '@storybook/core-events/server-errors';
import { storybookDevServer } from './dev-server';
import { outputStats } from './utils/output-stats';
import { outputStartupInformation } from './utils/output-startup-information';
Expand Down Expand Up @@ -89,7 +90,9 @@ export async function buildDevStandalone(

const { renderer, builder, disableTelemetry } = await presets.apply<CoreConfig>('core', {});

invariant(builder, 'No builder configured in core.builder');
if (!builder) {
throw new MissingBuilderError();
}

if (!options.disableTelemetry && !disableTelemetry) {
if (versionCheck.success && !versionCheck.cached) {
Expand Down
6 changes: 5 additions & 1 deletion code/lib/core-server/src/dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { CoreConfig, Options, StorybookConfig } from '@storybook/types';
import { logConfig } from '@storybook/core-common';

import { logger } from '@storybook/node-logger';
import { MissingBuilderError } from '@storybook/core-events/server-errors';
import { getMiddleware } from './utils/middleware';
import { getServerAddresses } from './utils/server-address';
import { getServer } from './utils/server-init';
Expand Down Expand Up @@ -67,7 +68,10 @@ export async function storybookDevServer(options: Options) {
server.listen({ port, host }, (error: Error) => (error ? reject(error) : resolve()));
});

invariant(core?.builder, 'no builder configured!');
if (!core?.builder) {
throw new MissingBuilderError();
}

const builderName = typeof core?.builder === 'string' ? core.builder : core?.builder?.name;

const [previewBuilder, managerBuilder] = await Promise.all([
Expand Down
8 changes: 6 additions & 2 deletions code/lib/core-server/src/utils/get-builders.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Builder, CoreConfig, Options } from '@storybook/types';
import { MissingBuilderError } from '@storybook/core-events/server-errors';
import { pathToFileURL } from 'node:url';
import invariant from 'tiny-invariant';

export async function getManagerBuilder(): Promise<Builder<unknown>> {
return import('@storybook/builder-manager');
Expand All @@ -20,7 +20,11 @@ export async function getPreviewBuilder(

export async function getBuilders({ presets, configDir }: Options): Promise<Builder<unknown>[]> {
const { builder } = await presets.apply<CoreConfig>('core', {});
invariant(builder, 'no builder configured!');

if (!builder) {
throw new MissingBuilderError();
}

const builderName = typeof builder === 'string' ? builder : builder.name;

return Promise.all([getPreviewBuilder(builderName, configDir), getManagerBuilder()]);
Expand Down