TanStack StartError HandlingTypeScriptReact

TanStack Start: Error Boundaries and Error Pages

Implement comprehensive error handling in TanStack Start, covering route-level error boundaries, server function error handling, custom error pages, and error monitoring.

Sam Rivera
Sam Rivera
June 11, 202610 min read

TL;DR: TanStack Start and TanStack Router provide a layered error handling system: route-level errorComponent, global error boundaries, and server function try/catch patterns. This guide covers custom error pages per route, global error monitoring integration, graceful server errors with user-friendly messages, and error recovery flows.


Introduction

Error handling is often an afterthought, but it directly impacts user trust and retention. A cryptic "Something went wrong" message frustrates users. A well-designed error page with context, recovery options, and a way to contact support builds confidence.

TanStack Start provides multiple layers for error handling, from React error boundaries to server-side error mappings.


Route-Level Error Components

TanStack Router lets you define an errorComponent per route, giving you granular control over error presentation. Here's a dashboard route with a custom error component that distinguishes between auth errors and generic failures:

tsx
// src/routes/dashboard.tsx
import { createFileRoute } from '@tanstack/react-router'
import { ErrorComponent } from '@tanstack/react-router'

export const Route = createFileRoute('/dashboard')({
  component: DashboardPage,
  errorComponent: ({ error, reset }) => (
    <div className="p-8 text-center">
      <h2 className="text-xl font-bold mb-2">Dashboard Error</h2>
      <p className="text-gray-600 mb-4">
        {error instanceof AuthError
          ? 'Your session expired. Please log in again.'
          : 'Unable to load dashboard. Please try again.'}
      </p>
      <div className="flex gap-4 justify-center">
        <button onClick={reset} className="btn-primary">Retry</button>
        <a href="/login" className="btn-secondary">Log In</a>
      </div>
      <details className="mt-4 text-xs text-gray-400">
        <summary>Technical Details</summary>
        <pre>{error.message}</pre>
      </details>
    </div>
  ),
})

The errorComponent receives both the error object and a reset function. The reset function clears the error boundary and re-renders the route, giving users a recovery path without navigating away. Categorizing errors (auth vs. generic) lets you show context-appropriate messages.

Global Error Boundary

For errors that escape route-level handling, set up a global error boundary in your root route. This catches any unhandled errors across all child routes:

tsx
// src/routes/__root.tsx
import { createRootRoute, Outlet } from '@tanstack/react-router'

export const Route = createRootRoute({
  component: () => (
    <ErrorBoundary fallback={<GlobalErrorPage />}>
      <Outlet />
    </ErrorBoundary>
  ),
})

The global error boundary acts as a safety net. If a route-level errorComponent fails or an unexpected error propagates, the global boundary renders a fallback UI that covers the entire application.

Server Function Error Handling

Server functions should catch and classify errors before they reach the client. Here's a pattern that differentiates database errors from other failures, logging critical issues while returning user-friendly messages:

tsx
export const fetchDataFn = createServerFn({ method: 'GET' })
  .handler(async () => {
    try {
      return await loadData()
    } catch (error) {
      if (error instanceof DatabaseError) {
        // Log for monitoring
        console.error('Database error:', error)
        // Return user-friendly response
        return { error: 'Data temporarily unavailable', retryAfter: 30 }
      }
      throw error // Let middleware handle it
    }
  })

This approach keeps your client-side code clean: the server function either returns data or a structured error response, and the client handles each case accordingly without parsing error messages.

Error Handling Strategy Table

LayerCatchesUser SeesRecovery
Zod validationInvalid inputField errorFix input
Server functionBusiness logicError message + retryRetry or contact
Route errorComponentRoute loading errorCustom error pageRetry or navigate
Global ErrorBoundaryAny uncaught errorFallback pageRefresh or support
onError (mutation)Mutation failureToastRollback UI

Conclusion

TanStack Start's layered error handling gives you control over every failure mode. Route-level error components provide context-specific recovery, while global boundaries catch anything that slips through. For deeper integration, combine error boundaries with Middleware and Request Lifecycle patterns, pair them with Nested Layouts and Auth Guards for protected routes, and wire up SaaS Monitoring and Observability for production error tracking.