Skip to content

bug when hydrating with error boundary #2539

@nitsky

Description

@nitsky

Hi, I am hydrating server rendered html and have an error boundary to handle client rendering errors. I am observing that if a component throws during hydration, both the original HTML and the "error" HTML are visible. You can reproduce the issue by opening the HTML below in a browser. You can uncomment the imports for react instead of preact to see the expected behavior.

Steps to reproduce

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf8" />
  </head>
  <body>
    <div id="root">
      <div>Hello, World!</div>
    </div>
    <script type="module">
      // use these imports to observe incorrect behavior with preact
      import {
        Component,
        createElement,
        hydrate,
      } from "https://cdn.pika.dev/preact@10.4.1";
      import { useState } from "https://cdn.pika.dev/preact@10.4.1/hooks";

      // use these imports instead to observe correct behavior with react
      // import {
      //   Component,
      //   createElement,
      //   useState,
      // } from "https://cdn.pika.dev/react";
      // import { hydrate } from "https://cdn.pika.dev/react-dom";

      class Root extends Component {
        constructor() {
          super();
          this.state = {};
        }
        componentDidCatch(error) {
          this.setState({ error });
        }
        render() {
          if (!this.state.error) {
            return createElement(App);
          } else {
            return createElement("div", {}, "Error!");
          }
        }
      }

      function App() {
        throw Error(); // <-- throwing here does not work as expected
        return createElement("div", {}, "Hello, World!");
      }

      hydrate(createElement(Root), document.getElementById("root"));
    </script>
  </body>
</html>

Expected Behavior

After hydration, "Hello, World!" should be replaced with "Error!" because the App component throws. When using the react imports instead of the preact imports in the file above, I see the expected behavior.

Actual Behavior

I see both "Hello, World!" and "Error!" below it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions