From 5929cf77f2b49efe6734d96f8969e9bdce854ad3 Mon Sep 17 00:00:00 2001 From: Jiwon Choi Date: Fri, 10 Jan 2025 16:48:38 +0800 Subject: [PATCH] [DevOverlay] Add Basic Stories for Error Containers (#74697) This PR added stories for Error containers: `Errors`, `BuildError`, `RootLayoutMissingTagsError`. Note: Filenames are Pascal for now to benefit the vscode file nesting. Will change all to kebab in once. --- .../internal/container/BuildError.stories.tsx | 34 ++++++ .../internal/container/Errors.stories.tsx | 102 +++++++++++++++--- .../RootLayoutMissingTagsError.stories.tsx | 35 ++++++ 3 files changed, 159 insertions(+), 12 deletions(-) create mode 100644 packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/BuildError.stories.tsx create mode 100644 packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/RootLayoutMissingTagsError.stories.tsx diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/BuildError.stories.tsx b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/BuildError.stories.tsx new file mode 100644 index 0000000000000..8f9b3413164f5 --- /dev/null +++ b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/BuildError.stories.tsx @@ -0,0 +1,34 @@ +import type { Meta, StoryObj } from '@storybook/react' +import { BuildError } from './BuildError' +import { withShadowPortal } from '../storybook/with-shadow-portal' + +const meta: Meta = { + title: 'BuildError', + component: BuildError, + parameters: { + layout: 'fullscreen', + }, + decorators: [withShadowPortal], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + args: { + message: `./src/app/page.tsx:3:3 +Parsing ecmascript source code failed + 1 | export default function Home() { + 2 | const +> 3 | return
Hello World
+ | ^^^^^^ + 4 | } + 5 | + +Expected identError: Failed to resolve import "./missing-module"`, + versionInfo: { + installed: '15.0.0', + staleness: 'fresh', + }, + }, +} diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/Errors.stories.tsx b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/Errors.stories.tsx index 5eda936d21737..adbeeea7325db 100644 --- a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/Errors.stories.tsx +++ b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/Errors.stories.tsx @@ -1,6 +1,7 @@ import type { Meta, StoryObj } from '@storybook/react' import { Errors } from './Errors' import { withShadowPortal } from '../storybook/with-shadow-portal' +import { ACTION_UNHANDLED_ERROR } from '../../../shared' const meta: Meta = { title: 'Errors', @@ -21,32 +22,109 @@ export const Default: Story = { { id: 1, event: { - type: 'unhandled-error', - reason: new Error('Failed to compile'), + type: ACTION_UNHANDLED_ERROR, + reason: new Error('First error message'), + componentStackFrames: [ + { + file: 'app/page.tsx', + component: 'Home', + lineNumber: 10, + column: 5, + canOpenInEditor: true, + }, + ], + frames: [ + { + file: 'app/page.tsx', + methodName: 'Home', + arguments: [], + lineNumber: 10, + column: 5, + }, + ], + }, + }, + { + id: 2, + event: { + type: ACTION_UNHANDLED_ERROR, + reason: new Error('Second error message'), + frames: [], + }, + }, + { + id: 3, + event: { + type: ACTION_UNHANDLED_ERROR, + reason: new Error('Third error message'), + frames: [], + }, + }, + { + id: 4, + event: { + type: ACTION_UNHANDLED_ERROR, + reason: new Error('Fourth error message'), frames: [], }, }, ], - initialDisplayState: 'fullscreen', versionInfo: { installed: '15.0.0', staleness: 'fresh', }, + initialDisplayState: 'fullscreen', hasStaticIndicator: true, isTurbopackEnabled: true, }, } -export const NoErrors: Story = { +export const Minimized: Story = { args: { - isAppDir: true, - errors: [], + ...Default.args, initialDisplayState: 'minimized', - versionInfo: { - installed: '15.0.0', - staleness: 'fresh', - }, - hasStaticIndicator: true, - isTurbopackEnabled: true, + }, +} + +export const WithHydrationWarning: Story = { + args: { + isAppDir: true, + errors: [ + { + id: 1, + event: { + type: ACTION_UNHANDLED_ERROR, + reason: Object.assign(new Error('Hydration error'), { + details: { + warning: [ + 'Text content does not match server-rendered HTML: "%s" !== "%s"', + 'Server Content', + 'Client Content', + ], + reactOutputComponentDiff: ` + +
+-

hello world

++
hello world
`, + }, + componentStackFrames: [ + { + component: 'MyComponent', + file: 'app/page.tsx', + lineNumber: 10, + columnNumber: 5, + }, + { + component: 'ParentComponent', + file: 'app/layout.tsx', + lineNumber: 20, + columnNumber: 3, + }, + ], + }), + frames: [], + }, + }, + ], }, } diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/RootLayoutMissingTagsError.stories.tsx b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/RootLayoutMissingTagsError.stories.tsx new file mode 100644 index 0000000000000..ff49e10c4cba9 --- /dev/null +++ b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/RootLayoutMissingTagsError.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from '@storybook/react' +import { RootLayoutMissingTagsError } from './RootLayoutMissingTagsError' +import { withShadowPortal } from '../storybook/with-shadow-portal' + +const meta: Meta = { + title: 'RootLayoutMissingTagsError', + component: RootLayoutMissingTagsError, + parameters: { + layout: 'fullscreen', + }, + decorators: [withShadowPortal], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + args: { + missingTags: ['html', 'body'], + versionInfo: { + installed: '15.0.0', + staleness: 'fresh', + }, + }, +} + +export const SingleTag: Story = { + args: { + missingTags: ['html'], + versionInfo: { + installed: '15.0.0', + staleness: 'fresh', + }, + }, +}