storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.41k stars 9.28k forks source link

[Bug]: @storybook/preset-create-react-app does not play nicely with error boundaries. #23165

Open dwjohnston opened 1 year ago

dwjohnston commented 1 year ago

Describe the bug

I have a component like this:

export function SomeComponent(props: { value: string }) {
    return (
        <ErrorBoundary>
            <SomeComponentInner {...props} />
        </ErrorBoundary>
    );
}

Where that SomeComponentInner will throw an error at render time.

So the expected (and actual behaviour for non CRA storybook configurations) behaviour is in Storybook the render error is thrown and the error boundary is displayed.

However, in a Storybook configuration for create-react-app we instead see this overlay error:

Screen Shot 2023-06-21 at 2 40 14 pm

We can click that close button, and see the error boundary.

However, this is a jarring experience. Also, it will be detected as an error by @storybook/test-runner.

To Reproduce

Repro for this here:

https://github.com/dwjohnston/storybook-cra/commit/7e68e968343851db8ad0604c5f9cb3100a7608cf

This is a basic create app application generated with:

yarn create react-app . --template=typescript 
npx storybook@latest init

Run yarn storybook and navigate to the Errored example.

System

Environment Info:

  System:
    OS: macOS 12.5.1
    CPU: (10) arm64 Apple M1 Pro
  Binaries:
    Node: 16.19.0 - ~/.nvm/versions/node/v16.19.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v16.19.0/bin/yarn
    npm: 9.6.2 - ~/.nvm/versions/node/v16.19.0/bin/npm
  Browsers:
    Chrome: 114.0.5735.133
    Edge: 114.0.1823.55
    Safari: 16.0
  npmPackages:
    @storybook/addon-essentials: ^7.0.22 => 7.0.22 
    @storybook/addon-interactions: ^7.0.22 => 7.0.22 
    @storybook/addon-links: ^7.0.22 => 7.0.22 
    @storybook/blocks: ^7.0.22 => 7.0.22 
    @storybook/preset-create-react-app: ^7.0.22 => 7.0.22 
    @storybook/react: ^7.0.22 => 7.0.22 
    @storybook/react-webpack5: ^7.0.22 => 7.0.22 
    @storybook/testing-library: ^0.0.14-next.2 => 0.0.14-next.2

Additional context

It appears that the overlay comes from this package:

https://github.com/pmmmwh/react-refresh-webpack-plugin

This behaviour can be solved by adding this to your storybook config in .storybook/main.js

  webpackFinal: (config) => {

    const refreshPluginIndex = config.plugins?.findIndex((v => v?.constructor.name === "ReactRefreshPlugin"));
    config.plugins[refreshPluginIndex].options.overlay = false;

    return config;
  }

Though this solution is a bit hamfisted - there are plenty of other cases where we do want to see the error overlay - ie. when we're not using an error boundary.

Also, this will still be detected as an error by @storybook/test-runner

pratyushvatsalshukla commented 9 months ago

Hi @shilman @dwjohnston I have re-generated your issue. below are my findings :

  1. No Try Block-Catch Block has been given : This is why error was not getting caught.
  2. Inside arguments of constructor,componentDidCatch, getDerivedStateFromError : Have to give error : any where "any" is the type which you need to define.

Attaching Below the Screenshot of the updated Output on Chrome : Screenshot 2024-01-25 172257 Screenshot 2024-01-25 172306

@dwjohnston I am creating a pull request in your repository. Request you to merge it.

dwjohnston commented 8 months ago

@pratyushvatsalshukla Have addressed your PR here. The repo linked intentionally creates a runtime error so that we can observe the behaviour of thrown errors/error boundaries in CRA + Storybook.