jpskill.com
🛠️ 開発・MCP コミュニティ

web-error-handling-error-boundaries

Reactアプリケーションでエラーが発生した際に、エラー境界パターンや代替UIを表示し、リセットや再試行を可能にすることで、ユーザー体験を向上させるエラー処理を実装するSkill。

📜 元の英語説明(参考)

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

🇯🇵 日本人クリエイター向け解説

一言でいうと

Reactアプリケーションでエラーが発生した際に、エラー境界パターンや代替UIを表示し、リセットや再試行を可能にすることで、ユーザー体験を向上させるエラー処理を実装するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o web-error-handling-error-boundaries.zip https://jpskill.com/download/10275.zip && unzip -o web-error-handling-error-boundaries.zip && rm web-error-handling-error-boundaries.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/10275.zip -OutFile "$d\web-error-handling-error-boundaries.zip"; Expand-Archive "$d\web-error-handling-error-boundaries.zip" -DestinationPath $d -Force; ri "$d\web-error-handling-error-boundaries.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して web-error-handling-error-boundaries.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → web-error-handling-error-boundaries フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

React のエラー境界

クイックガイド: エラー境界は、コンポーネントツリー内の JavaScript エラーをキャッチし、フォールバック UI を表示します。本番環境のアプリには、react-error-boundary ライブラリ (v6+) を使用してください。境界は、ルートだけでなく、機能の周りに戦略的に配置します。境界は、イベントハンドラ、非同期、または SSR エラーをキャッチしません -- 非同期には showBoundary() フックを使用してください。React 19+: 集中型エラーロギングには、createRoot オプション (onCaughtError, onUncaughtError, onRecoverableError) を使用してください。


<critical_requirements>

重要: このスキルを使用する前に

すべてのコードは、CLAUDE.md のプロジェクト規約に従う必要があります (kebab-case, 名前付きエクスポート, インポート順, import type, 名前付き定数)

(フォールバック UI のレンダリングには getDerivedStateFromError を使用する必要があります - レンダリングフェーズ中に実行されます)

(ロギングのような副作用には componentDidCatch を使用する必要があります - コミットフェーズ中に実行されます)

(エラー境界は、アプリのルートだけでなく、機能セクションの周りにラップする必要があります)

(回復可能なエラーには、リセット/再試行機能を提供する必要があります)

(アクセシビリティのために、フォールバック UI に role="alert" を使用する必要があります)

</critical_requirements>


自動検出: error boundary, ErrorBoundary, getDerivedStateFromError, componentDidCatch, fallback UI, react-error-boundary, useErrorBoundary, showBoundary, error recovery, error fallback, onCaughtError, onUncaughtError, onRecoverableError, captureOwnerStack, FallbackProps, resetKeys

使用する場面:

  • レンダリングエラーのキャッチとフォールバック UI の表示
  • エラー後の再試行/リセット機能の実装
  • コンポーネントの障害によるアプリ全体のクラッシュの防止
  • さまざまな機能に対する分離された障害ドメインの作成

カバーする主なパターン:

  • クラスベースのエラー境界の実装
  • react-error-boundary ライブラリのパターン (v6+)
  • 非同期エラーに対する showBoundary() を伴う useErrorBoundary フック
  • リセット機能と role="alert" を備えたフォールバック UI
  • 戦略的な境界配置 (粒度の細かいものと粗いもの)
  • 自動境界リセットのための resetKeys
  • React 19+: 集中型ロギングのための createRoot エラーオプション
  • React 19+: 拡張されたデバッグのための captureOwnerStack()

使用しない場面:

  • イベントハンドラのエラー (try/catch を使用)
  • コンポーネント外の非同期コードのエラー (try/catch または showBoundary を使用)
  • サーバーサイドレンダリングのエラー (フレームワークレベルで処理)
  • API リクエストのエラー (データ取得レイヤーで処理)

詳細なリソース:

  • examples/core.md - 完全な境界の実装、ライブラリの使用法、粒度の細かい配置
  • examples/react-19-hooks.md - createRoot エラーオプション、captureOwnerStack、エラーフィルタリング
  • examples/recovery.md - 再試行制限、指数バックオフ、エラー分類
  • examples/testing.md - 境界のテスト、非同期エラー、resetKeys
  • reference.md - 意思決定フレームワーク、アンチパターン、チェックリスト

<philosophy>

哲学

エラー境界は グレースフルデグラデーション を提供します -- 1 つのコンポーネントが失敗しても、アプリケーションの残りの部分は動作し続けます。重要な原則は 分離 です。個別の機能を個別の境界でラップして、障害を封じ込めます。エラー境界は、React レンダリング中にエラーをキャッチする唯一の方法です。命令型コードの try/catch を補完します。

コア原則:

  1. グローバルな処理よりも分離 - 複数の粒度の細かい境界は、1 つのルート境界に勝ります
  2. 失敗よりも回復 - 可能な場合はリセット/再試行を提供します
  3. 沈黙の失敗よりもユーザーフィードバック - 意味のある、アクセス可能なフォールバック UI を表示します
  4. ロギングの統合 - onError コールバックを介してエラーを監視に渡します
  5. 集中型の可観測性 (React 19+) - 統合されたエラートラッキングのために createRoot エラーオプションを使用します

</philosophy>


<patterns>

コアパターン

パターン 1: クラスベースのエラー境界 (ネイティブ React)

エラー境界はクラスコンポーネントでなければなりません -- getDerivedStateFromErrorcomponentDidCatch にはフックの同等物はありません。

2 つのライフサイクルメソッド

メソッド フェーズ 目的 副作用
getDerivedStateFromError レンダリング フォールバックを表示するために状態を更新 許可されない
componentDidCatch コミット エラーのログ記録、コールバックの呼び出し 許可される
// ✅ 良い - リセットを備えた完全なエラー境界
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>何かがうまくいきませんでした</h2>
          <button onClick={this.handleReset}>もう一度試してください</button>
        </div>
      );
    }
    return children;
  }
}

良い理由: レンダリングフェーズ/コミットフェーズの分離、リセット機能、柔軟なフォールバック API、onError により、特定のツールに結合せずにロギングが可能

(原文がここで切り詰められています)

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

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:


<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>
      );
    }
    return children;
  }
}

Why good: Render-phase/commit-phase separation, reset capability, flexible fallback API, onError enables logging without coupling to specific tools


Pattern 2: react-error-boundary Library (v6+)

Production-ready error boundary with hooks support, resetKeys, and useErrorBoundary.

npm install react-error-boundary
Prop Type Purpose
fallback ReactNode Static fallback UI
FallbackComponent ComponentType Component that renders fallback
fallbackRender (props) => ReactNode Render prop for fallback
onError (error, info) => void Error logging callback
onReset (details) => void Called when boundary resets
resetKeys unknown[] Dependencies that trigger reset
// ✅ Good - FallbackComponent pattern
import { ErrorBoundary } from "react-error-boundary";
import type { FallbackProps } from "react-error-boundary";

function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
  return (
    <div role="alert">
      <h2>Something went wrong</h2>
      <pre>{error.message}</pre>
      <button onClick={resetErrorBoundary}>Try again</button>
    </div>
  );
}

export function App() {
  return (
    <ErrorBoundary
      FallbackComponent={ErrorFallback}
      onError={(error, info) => {
        // Send to your error monitoring service
        console.error("Boundary caught:", error, info);
      }}
    >
      <Dashboard />
    </ErrorBoundary>
  );
}

Why good: Reusable FallbackComponent, onError decouples logging, onReset enables state cleanup

See examples/core.md for resetKeys, useErrorBoundary, and granular placement examples.


Pattern 3: useErrorBoundary Hook (Async Errors)

Error boundaries don't catch async errors. Use showBoundary() from useErrorBoundary to manually trigger the nearest boundary.

// ❌ This async error is NOT caught by error boundary
async function handleClick() {
  throw new Error("API failed"); // Lost - boundary doesn't see it
}
// ✅ Good - showBoundary propagates async errors
import { useErrorBoundary } from "react-error-boundary";

function DataLoader() {
  const { showBoundary } = useErrorBoundary();

  const handleLoadData = async () => {
    try {
      const response = await fetch("/api/data");
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      // ... handle success
    } catch (error) {
      showBoundary(error); // Manually trigger nearest boundary
    }
  };

  return <button onClick={handleLoadData}>Load Data</button>;
}

Why good: Propagates async errors to boundary, consistent error UI across sync/async failures

Use showBoundary for: Async operations, event handlers, effects that should show fallback UI on failure. Do NOT use for: Errors handled locally with inline UI, validation errors needing field-level feedback.


Pattern 4: resetKeys for Automatic Reset

Use resetKeys to auto-reset the boundary when certain values change (e.g., route, selected item).

// ✅ Good - Reset boundary on route change
<ErrorBoundary
  FallbackComponent={ErrorFallback}
  resetKeys={[location.pathname]}
>
  <Routes />
</ErrorBoundary>
Pattern Use Case
[pathname] Reset on route change
[selectedId] Reset when viewing different item
[retryCount] Reset after programmatic retry

Gotcha: resetKeys comparison is shallow -- objects/arrays need stable references.


Pattern 5: Granular Boundary Placement

App
├─ ErrorBoundary (root - last-resort catch-all)
│   ├─ Header
│   ├─ ErrorBoundary (sidebar)
│   │   └─ Sidebar
│   ├─ ErrorBoundary (main content)
│   │   ├─ ErrorBoundary (widget A)
│   │   │   └─ ChartWidget
│   │   └─ ErrorBoundary (widget B)
│   │       └─ TableWidget
│   └─ Footer
// ✅ Good - Granular boundaries isolate failures
function Dashboard() {
  return (
    <div>
      <ErrorBoundary fallback={<div>Chart unavailable</div>} onError={logError}>
        <ChartWidget />
      </ErrorBoundary>
      <ErrorBoundary fallback={<div>Table unavailable</div>} onError={logError}>
        <DataTable />
      </ErrorBoundary>
    </div>
  );
}

Why good: One widget failing doesn't crash the dashboard, each feature has contextual fallback

// ❌ Bad - Single boundary for everything
<ErrorBoundary fallback={<div>Dashboard error</div>}>
  <ChartWidget />
  <DataTable />
  <StatsPanel />
</ErrorBoundary>

Why bad: One failing widget crashes entire dashboard, users lose access to working features


Pattern 6: Fallback UI

Fallback UI must include role="alert" for accessibility, retry button for recovery, and hide error details in production.

// ✅ Good - Environment-aware fallback with accessibility
function DetailedFallback({ error, resetErrorBoundary }: FallbackProps) {
  const isDev = process.env.NODE_ENV === "development";
  return (
    <div role="alert">
      <h2>Something went wrong</h2>
      {isDev && (
        <details>
          <summary>Error details</summary>
          <pre>{error.message}</pre>
        </details>
      )}
      <button onClick={resetErrorBoundary}>Try again</button>
      <button onClick={() => window.location.reload()}>Refresh page</button>
    </div>
  );
}

Why good: role="alert" announces to screen readers, dev-only details, multiple recovery options

// ❌ Bad - Missing accessibility, raw errors in production
<div>
  <pre>{error.stack}</pre>
  <span onClick={reset}>Retry</span> {/* Not keyboard accessible */}
</div>

Why bad: No role="alert", exposes internals to users, span not keyboard-accessible


Pattern 7: React 19+ createRoot Error Options

React 19 adds three root-level error handlers for centralized logging. These complement (not replace) ErrorBoundary components.

Handler When Called Use Case
onCaughtError Error caught by an ErrorBoundary Log handled errors
onUncaughtError Error NOT caught by any boundary Log fatal errors
onRecoverableError React auto-recovers from error Log hydration mismatches, suspense errors
// ✅ Good - Centralized error logging with createRoot
import { createRoot } from "react-dom/client";

const ROOT_ELEMENT_ID = "root";
const container = document.getElementById(ROOT_ELEMENT_ID);
if (!container) throw new Error("Root element not found");

const root = createRoot(container, {
  onCaughtError: (error, errorInfo) => {
    reportToMonitoring("caught", error, errorInfo.componentStack);
  },
  onUncaughtError: (error, errorInfo) => {
    reportToMonitoring("uncaught", error, errorInfo.componentStack);
  },
  onRecoverableError: (error, errorInfo) => {
    reportToMonitoring("recoverable", error, errorInfo.componentStack);
  },
});
root.render(<App />);

Why good: Single configuration point for all React error logging, catches errors that escape all boundaries

See examples/react-19-hooks.md for captureOwnerStack(), error filtering, and hydrateRoot patterns.

</patterns>


<red_flags>

RED FLAGS

High Priority:

  • Missing error boundaries entirely -- app crashes on any render error
  • Single root boundary only -- no isolation between features
  • No reset/retry functionality -- users must refresh page
  • Missing role="alert" on fallback -- screen readers don't announce errors
  • Side effects in getDerivedStateFromError -- violates React phase rules

Medium Priority:

  • Not using showBoundary() for async errors -- they silently fail
  • Same fallback for all boundaries -- no context about what failed
  • No onError callback -- errors not reported to monitoring
  • Overly granular boundaries (every component) -- unnecessary overhead

Gotchas & Edge Cases:

  • getDerivedStateFromError runs during render -- no side effects allowed
  • Error boundaries don't catch errors in themselves -- only children
  • Nested boundaries: innermost boundary catches first
  • Hot reload can trigger boundaries in development (expected behavior)
  • resetKeys comparison is shallow -- objects/arrays need stable references
  • SSR hydration errors may not be caught by client-side boundaries
  • React 19: captureOwnerStack() returns null in production
  • React 19: onCaughtError runs AFTER boundary's componentDidCatch, not before
  • React 19: onRecoverableError may have error.cause with the original thrown error
  • React 19: These options are silently ignored on React 18

</red_flags>


<critical_reminders>

CRITICAL REMINDERS

All code must follow project conventions in CLAUDE.md

(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)

Failure to follow these rules will result in poor error handling, inaccessible UIs, or unrecoverable error states.

</critical_reminders>