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本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
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
$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. 下の青いボタンを押して
web-error-handling-error-boundaries.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
web-error-handling-error-boundariesフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
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 つのルート境界に勝ります
- 失敗よりも回復 - 可能な場合はリセット/再試行を提供します
- 沈黙の失敗よりもユーザーフィードバック - 意味のある、アクセス可能なフォールバック UI を表示します
- ロギングの統合 -
onErrorコールバックを介してエラーを監視に渡します - 集中型の可観測性 (React 19+) - 統合されたエラートラッキングのために
createRootエラーオプションを使用します
</philosophy>
<patterns>
コアパターン
パターン 1: クラスベースのエラー境界 (ネイティブ React)
エラー境界はクラスコンポーネントでなければなりません -- getDerivedStateFromError と componentDidCatch にはフックの同等物はありません。
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-boundarylibrary (v6+) for production apps. Place boundaries strategically around features, not just root. Boundaries do NOT catch event handler, async, or SSR errors -- useshowBoundary()hook for async. React 19+: UsecreateRootoptions (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-boundarylibrary patterns (v6+)useErrorBoundaryhook withshowBoundary()for async errors- Fallback UI with reset functionality and
role="alert" - Strategic boundary placement (granular vs coarse)
resetKeysfor automatic boundary reset- React 19+:
createRooterror 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 - Complete boundary implementations, library usage, granular placement
- examples/react-19-hooks.md - createRoot error options, captureOwnerStack, error filtering
- examples/recovery.md - Retry limits, exponential backoff, error classification
- examples/testing.md - Testing boundaries, async errors, resetKeys
- 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:
- Isolation over global handling - Multiple granular boundaries beat one root boundary
- Recovery over failure - Provide reset/retry when possible
- User feedback over silent failure - Show meaningful, accessible fallback UI
- Logging integration - Pass errors to monitoring via
onErrorcallback - Centralized observability (React 19+) - Use
createRooterror 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
onErrorcallback -- errors not reported to monitoring - Overly granular boundaries (every component) -- unnecessary overhead
Gotchas & Edge Cases:
getDerivedStateFromErrorruns 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)
resetKeyscomparison is shallow -- objects/arrays need stable references- SSR hydration errors may not be caught by client-side boundaries
- React 19:
captureOwnerStack()returnsnullin production - React 19:
onCaughtErrorruns AFTER boundary'scomponentDidCatch, not before - React 19:
onRecoverableErrormay haveerror.causewith 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>