Svelte logo

Svelte by Example: Error Boundaries

An error boundary can replace part of the interface when rendering fails, without removing the rest of the page.

In this example, we'll recover from a todo that can't be rendered.

This function runs while rendering. The button changes the data; the error is thrown on the next render, not in the event handler.

A boundary with a failed snippet catches rendering errors inside it and removes the failed content.

Fix the data before calling reset. It recreates the boundary's contents; retrying with the same broken data would fail again.

TodoList.svelte
<script>
  let task = $state('Walk dog');


  function renderTask(value) {
    if (!value) throw new Error('This todo needs a task.');
    return value;
  }
</script>

<h1>Todo List</h1>
<button onclick={() => task = ''}>Try a broken todo</button>



<svelte:boundary>
  <p>{renderTask(task)}</p>

  {#snippet failed(error, reset)}
    <p>Couldn't show this todo: {error.message}</p>


    <button onclick={() => {
      task = 'Walk dog';
      reset();
    }}>Restore and retry</button>
  {/snippet}
</svelte:boundary>

Boundaries also catch errors while running effects. They don't catch errors thrown in event handlers, timers, or async callbacks. Handle those where they happen; use an await block's :catch for a rejected promise.

Server-side error handling depends on the renderer or framework configuration. Svelte's server render API supports it with transformError; don't send private error details to the browser. Our example starts with a valid todo so the initial server render can succeed.