Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Handling errors: ErrorBoundary

If an error happens in a component — for example, the server did not respond — the whole page breaks without protection. An error boundary (ErrorBoundary) catches errors inside it and shows a fallback UI in place of the broken part, while the rest of the page keeps working.

ErrorBoundary

// src/App.jsx
import { ErrorBoundary } from 'solid-js';
import PostList from './components/PostList';
 
export default function App() {
  return (
    <main>
      <h1>Blog</h1>
      <ErrorBoundary fallback={<p>Could not load posts.</p>}>
        <PostList />
      </ErrorBoundary>
    </main>
  );
}

If PostList throws an error, "Could not load posts." appears instead of the list, and the "Blog" heading stays in place.

A loading error

fetch does not treat a 404 or 500 response as an error, so you check the status yourself and throw:

// src/components/PostList.jsx
import { createResource, For } from 'solid-js';
 
const fetchPosts = async () => {
  const res = await fetch('https://jsonplaceholder.typicode.com/postss');
  if (!res.ok) throw new Error(`Server error: ${res.status}`);
  return res.json();
};
 
export default function PostList() {
  const [posts] = createResource(fetchPosts);
 
  return (
    <ul>
      <For each={posts()}>{(post) => <li>{post.title}</li>}</For>
    </ul>
  );
}

The address has a deliberate typo, postss, so the server returns 404. The resource goes into the error state, and reading posts() passes the error to the nearest ErrorBoundary.

Message and retry

You can pass a function to fallback. It receives the error and a reset function that renders the boundary's content again:

// src/App.jsx
import { ErrorBoundary } from 'solid-js';
import PostList from './components/PostList';
 
export default function App() {
  return (
    <ErrorBoundary
      fallback={(err, reset) => (
        <div>
          <p>{err.message}</p>
          <button onClick={reset}>Try again</button>
        </div>
      )}
    >
      <PostList />
    </ErrorBoundary>
  );
}

The page shows "Server error: 404" and a button. After you fix the address in fetchPosts, clicking the button renders PostList again.

Together with Suspense

ComponentWhat it shows
SuspenseFallback content while data is loading
ErrorBoundaryFallback content if loading or rendering failed

They are usually used together: ErrorBoundary outside, Suspense inside, and the data component deeper still.

What is not caught

ErrorBoundary catches errors during rendering, in effects and in resources. Errors in event handlers, such as onClick, do not reach it — handle them with an ordinary try...catch inside the handler.

Common mistake

Wrapping the entire app in a single ErrorBoundary. Then an error in a small comments widget replaces the whole page with a message. Put boundaries around independent parts: the post list, the comments, the sidebar.

Thanks for reading!

Donate to the site — we work hard for you.