solidjs / solid-meta

Write meta tags to the document head
127 stars 16 forks source link

Thrown errors in cache data from solid-router in Meta components not caught by ErrorBoundary #49

Open paularmstrong opened 2 months ago

paularmstrong commented 2 months ago

Expected behavior:

Rendering from cached responses from solid-router within meta components, eg:

<Title>{house()}</Title>

Should be able to be caught by a parent ErrorBoundary

Actual behavior:

Solid-start crashes with the thrown error.

Hacky easy to forget fix:

Ensure meta components are wrapped in a <Show> :\

<Show when={house()}><Title>{house()}</Title></Show>

Unfortunately:

[!WARNING] This will log a warning in the client:

computations created outside a `createRoot` or `render` will never be disposed

[!IMPORTANT] On further testing, it seems that this causes other issues: when client-side routing with @solidjs/router and house() throws an error, the route won't load and further client side navigation will not resolve. Potentially related to the above warning?

Repro:

https://stackblitz.com/edit/github-1j1ryx?file=src%2Froutes%2Findex.tsx

import { Title } from '@solidjs/meta';
import Counter from '~/components/Counter';
import { Show, ErrorBoundary } from 'solid-js';
import { cache, createAsync } from '@solidjs/router';
import { HttpStatusCode } from '@solidjs/start';

const getHouse = cache(async (house: string) => {
  if (house != 'gryffindor') {
    throw new Error('House not found');
  }
  return house;
}, 'house');

export default function Home() {
  const house = createAsync(() => getHouse('foo'));

  return (
    <ErrorBoundary fallback={<div>fallback okay</div>}>
      <main>
        {/* it's expected this would get caught by the error boundaryu, but it crashes the server */}
        <Title>{house()}</Title>
        {/* FIX: need to wrap <Title> in a <Show>??
        <Show when={house()}><Title>{house()}</Title></Show>
        */}
        <h1>Hello world!</h1>
        <Counter />
        <p>
          Visit{' '}
          <a href="https://start.solidjs.com" target="_blank">
            start.solidjs.com
          </a>{' '}
          to learn how to build SolidStart apps.
        </p>
      </main>
    </ErrorBoundary>
  );
}