Skip to content

/web-error-handling-error-boundaries

Error boundary patterns, fallback UI, reset/retry, react-error-boundary library, React 19 createRoot error hooks

shell
$ npx -y skills add agents-inc/skills --skill web-error-handling-error-boundaries --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/web-error-handling-error-boundaries
How auto-invocation works

Context preview

The summary Claude sees to decide when to auto-load this skill.

Error boundary patterns, fallback UI, reset/retry, react-error-boundary library, React 19 createRoot error hooks

SKILL.md

web-error-handling-error-boundaries.SKILL.md
name: web-error-handling-error-boundaries
description: Error boundary patterns, fallback UI, reset/retry, react-error-boundary library, React 19 createRoot error hooks

React Error Boundaries

> **Quick Guide:** Error boundaries catch JavaScript errors in component trees and display fallback UI. Use `react-error-boundary` library (v6+) for production apps. Place boundaries strategically around features, not just root. Boundaries do NOT catch event handler, async, or SSR errors -- use `showBoundary()` hook for async. **React 19+**: Use `createRoot` options (`onCaughtError`, `onUncaughtError`, `onRecoverableError`) for centralized error logging.

---

<critical_requirements>

CRITICAL: Before Using This Skill

> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)

**(You MUST use `getDerivedStateFromError` for rendering fallback UI - it runs during render phase)**

**(You MUST use `componentDidCatch` for side effects like logging - it runs during commit phase)**

**(You MUST wrap error boundaries around feature sections, not just the app root)**

**(You MUST provide reset/retry functionality for recoverable errors)**

**(You MUST use `role="alert"` on fallback UI for accessibility)**

</critical_requirements>

---

**Auto-detection:** error boundary, ErrorBoundary, getDerivedStateFromError, componentDidCatch, fallback UI, react-error-boundary, useErrorBoundary, showBoundary, error recovery, error fallback, onCaughtError, onUncaughtError, onRecoverableError, captureOwnerStack, FallbackProps, resetKeys

**When to use:**

  • Catching and displaying fallback UI for render errors
  • Implementing retry/reset functionality after errors
  • Preventing entire app crashes from component failures
  • Creating isolated failure domains for different features

**Key patterns covered:**

  • Class-based error boundary implementation
  • `react-error-boundary` library patterns (v6+)
  • `useErrorBoundary` hook with `showBoundary()` for async errors
  • Fallback UI with reset functionality and `role="alert"`
  • Strategic boundary placement (granular vs coarse)
  • `resetKeys` for automatic boundary reset
  • **React 19+**: `createRoot` error options for centralized logging
  • **React 19+**: `captureOwnerStack()` for enhanced debugging

**When NOT to use:**

  • Event handler errors (use try/catch)
  • Async code errors outside components (use try/catch or showBoundary)
  • Server-side rendering errors (handle at framework level)
  • API request errors (handle in your data fetching layer)

**Detailed Resources:**

  • [examples/core.md](examples/core.md) - Complete boundary implementations, library usage, granular placement
  • [examples/react-19-hooks.md](examples/react-19-hooks.md) - createRoot error options, captureOwnerStack, error filtering
  • [examples/recovery.md](examples/recovery.md) - Retry limits, exponential backoff, error classification
  • [examples/testing.md](examples/testing.md) - Testing boundaries, async errors, resetKeys
  • [reference.md](reference.md) - Decision frameworks, anti-patterns, checklists

---

<philosophy>

Philosophy

Error boundaries provide **graceful degradation** -- when one component fails, the rest of the application continues working. The key principle is **isolation**: wrap distinct features in separate boundaries so failures are contained. Error boundaries are the ONLY way to catch errors during React rendering; they complement try/catch for imperative code.

**Core principles:**

1. **Isolation over global handling** - Multiple granular boundaries beat one root boundary 2. **Recovery over failure** - Provide reset/retry when possible 3. **User feedback over silent failure** - Show meaningful, accessible fallback UI 4. **Logging integration** - Pass errors to monitoring via `onError` callback 5. **Centralized observability (React 19+)** - Use `createRoot` error options for unified error tracking

</philosophy>

---

<patterns>

Core Patterns

Pattern 1: Class-Based Error Boundary (Native React)

Error boundaries MUST be class components -- `getDerivedStateFromError` and `componentDidCatch` have no hook equivalents.

Two Lifecycle Methods

| Method | Phase | Purpose | Side Effects | | -------------------------- | ------ | ----------------------------- | ------------ | | `getDerivedStateFromError` | Render | Update state to show fallback | NOT allowed | | `componentDidCatch` | Commit | Log errors, call callbacks | Allowed |

// ✅ Good - Complete error boundary with reset
import { Component } from "react";
import type { ErrorInfo, ReactNode } from "react";

interface ErrorBoundaryProps {
  children: ReactNode;
  fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);
  onError?: (error: Error, errorInfo: ErrorInfo) => void;
  onReset?: () => void;
}

interface ErrorBoundaryState {
  hasError: boolean;
  error: Error | null;
}

export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
  constructor(props: ErrorBoundaryProps) {
    super(props);
    this.state = { hasError: false, error: null };
  }

  static getDerivedStateFromError(error: Error): ErrorBoundaryState {
    return { hasError: true, error };
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
    this.props.onError?.(error, errorInfo);
  }

  handleReset = (): void => {
    this.props.onReset?.();
    this.setState({ hasError: false, error: null });
  };

  render(): ReactNode {
    const { hasError, error } = this.state;
    const { children, fallback } = this.props;

    if (hasError && error) {
      if (typeof fallback === "function") return fallback(error, this.handleReset);
      if (fallback) return fallback;
      return (
        <div role="alert">
          <h2>Something went wrong</h2>
          <button onClick={this.handleReset}>Try again</button>
        </div>
      );
    }
    retur
Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withagents-inc-skills

The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?

Get the whole plugin, auto-invoked