DEV Community

Cover image for Handling errors in Remix
Chris Bongers
Chris Bongers

Posted on • Originally published at daily-dev-tips.com

Handling errors in Remix

It's always annoying if your application throws unforeseen errors.

In general, it's good advice to build in the most common error catching early on. However, there might be some generic errors you can't always see coming.

Luckily for us, Remix will catch most of these errors and can render them to the closest ErrorBoundary box we define.

Creating a root error boundary

From my perspective, you'll always want to add a root error boundary to your code, this is the topmost level, so if an error is thrown top-level, this one will always be able to catch it.

To create one of these root error boundaries, open up the root.tsx file.

According to the docs, it's best to render a full HTML for the root error boundary as it will mount and unmount on the render of this error.
By having access to the <Meta />, <Links />, and <Script /> tags, it might be able to re-render.

Let's add the following function to this root file:

export function ErrorBoundary({ error }) {
  return (
    <html>
      <head>
        <title>Oh no!</title>
        <Meta />
        <Links />
      </head>
      <body className='m-4'>
        <h1 className='text-2xl'>Something went wrong!</h1>
        <p>{error.message}</p>
        <Scripts />
      </body>
    </html>
  );
}
Enter fullscreen mode Exit fullscreen mode

Let's try it out and see what happens; I added this particular error in app/routes/admin/posts/index.tsx.

export function loader() {
  throw new Error('I am a failure!');
}
Enter fullscreen mode Exit fullscreen mode

And if we now open this page, we get hit by the following error.

Error boundary in Remix

This is already way better than not throwing a custom error.
The downside is blocking the complete page while our error is only thrown down the line.

Adding nested error boundaries

And this is where Remix kind of blows my mind. It supports multiple error boundaries!

Remix will start looking for the closest error boundary to render the error when an error is thrown.

We could add an error boundary in the same file we throw it in in our case.

export function ErrorBoundary({ error }) {
  return (
    <div className='bg-red-100 border border-red-300 p-4'>
      <h1 className='text-2xl'>Something went wrong!</h1>
      <p>{error.message}</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Now refresh the page and see what happens.

Nested error boundary

Wow, the error is only shown in the specific nested route!
The other parts of our application are still working as expected.

You can find this example code on GitHub.

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Top comments (0)