
Error Boundary Creator
- 227 installs
- 237 repo stars
- Updated July 15, 2026
- onewave-ai/claude-skills
Scaffold React error boundary components with fallback UI, logging hooks, and recovery patterns for client-side failures.
About
Builds production-ready React error boundary components with sensible fallback UI, isolation boundaries, and logging hooks so client render failures degrade gracefully instead of blanking the whole app.
- Fallback UI templates
- Component isolation
- Error logging hooks
- Recovery patterns
- TypeScript-ready scaffolds
Error Boundary Creator by the numbers
- 227 all-time installs (skills.sh)
- +6 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #828 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/onewave-ai/claude-skills --skill error-boundary-creatorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 227 |
|---|---|
| repo stars | ★ 237 |
| Last updated | July 15, 2026 |
| Repository | onewave-ai/claude-skills ↗ |
What it does
Scaffold React error boundary components with fallback UI, logging hooks, and recovery patterns for client-side failures.
Files
Error Boundary Creator
Add resilient error handling to React and Next.js apps: error boundaries, fallback UIs, async error handling, and error reporting.
Workflow
1. Identify error-prone areas: async operations, third-party integrations, and route-level entry points. 2. Wrap components in an error boundary. Use a class boundary or the react-error-boundary library. See references/class-boundaries.md. 3. For Next.js App Router, add the relevant error.tsx, global-error.tsx, and not-found.tsx segment files. See references/nextjs-error-handling.md. 4. Handle errors that boundaries miss (event handlers, promises) and wire up reporting. See references/async-and-reporting.md. 5. Design fallback UIs with role="alert" and a recovery action (reset or reload). 6. Route caught errors to a single reporting sink and test error states before shipping.
Contents
- references/class-boundaries.md — Basic, resettable, and
react-error-boundarypatterns. - references/nextjs-error-handling.md — App Router
error.tsx,global-error.tsx,not-found.tsx. - references/async-and-reporting.md —
useAsynchook and thereportErrorintegration module.
Best Practices
1. Wrap at the route level for page-level isolation, and wrap third-party components separately. 2. Provide meaningful fallbacks with a recovery option. 3. Log every caught error to the monitoring service. 4. Do not catch errors the code cannot meaningfully handle. 5. Test error states in development.
Async Error Handling and Error Reporting
Error boundaries do not catch errors in event handlers, async callbacks, or promises. Handle those explicitly with the patterns below.
Async Error Handling Hook
Track loading, data, and error state for async operations so the UI can render a retry path.
'use client';
import { useState } from 'react';
interface AsyncState<T> {
data: T | null;
error: Error | null;
isLoading: boolean;
}
function useAsync<T>() {
const [state, setState] = useState<AsyncState<T>>({
data: null,
error: null,
isLoading: false,
});
const execute = async (promise: Promise<T>) => {
setState({ data: null, error: null, isLoading: true });
try {
const data = await promise;
setState({ data, error: null, isLoading: false });
return data;
} catch (error) {
setState({ data: null, error: error as Error, isLoading: false });
throw error;
}
};
return { ...state, execute };
}
// Usage
function DataComponent() {
const { data, error, isLoading, execute } = useAsync<User[]>();
const loadData = () => execute(fetchUsers());
if (isLoading) return <Spinner />;
if (error) return <ErrorMessage error={error} onRetry={loadData} />;
if (!data) return <button onClick={loadData}>Load</button>;
return <UserList users={data} />;
}Error Reporting Integration
Centralize reporting in one module so boundaries and async handlers share a single sink. Swap in the provider (Sentry, LogRocket, custom endpoint) used by the project.
// lib/error-reporting.ts
export function reportError(error: Error, context?: Record<string, unknown>) {
// Sentry
// Sentry.captureException(error, { extra: context });
// LogRocket
// LogRocket.captureException(error);
// Custom endpoint
fetch('/api/errors', {
method: 'POST',
body: JSON.stringify({
message: error.message,
stack: error.stack,
context,
timestamp: new Date().toISOString(),
url: window.location.href,
userAgent: navigator.userAgent,
}),
}).catch(console.error);
}Class Component Error Boundaries
React error boundaries must be class components. Use these patterns for the boundary itself; fallback UIs can be function components.
Basic Error Boundary
'use client';
import { Component, ErrorInfo, ReactNode } from 'react';
interface Props {
children: ReactNode;
fallback?: ReactNode;
}
interface State {
hasError: boolean;
error?: Error;
}
export class ErrorBoundary extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error: Error): State {
return { hasError: true, error };
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
console.error('Error caught by boundary:', error, errorInfo);
// Send to error reporting service
// reportError(error, errorInfo);
}
render() {
if (this.state.hasError) {
return this.props.fallback || <DefaultErrorFallback error={this.state.error} />;
}
return this.props.children;
}
}
function DefaultErrorFallback({ error }: { error?: Error }) {
return (
<div role="alert" className="p-4 bg-red-50 border border-red-200 rounded-lg">
<h2 className="text-lg font-semibold text-red-800">Something went wrong</h2>
<p className="text-red-600 mt-1">{error?.message || 'An unexpected error occurred'}</p>
<button
onClick={() => window.location.reload()}
className="mt-4 px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700"
>
Reload page
</button>
</div>
);
}Error Boundary with Reset
Expose a reset handler so the user can recover without a full page reload.
'use client';
import { Component, ReactNode } from 'react';
interface Props {
children: ReactNode;
onReset?: () => void;
}
interface State {
hasError: boolean;
error?: Error;
}
export class ResettableErrorBoundary extends Component<Props, State> {
state: State = { hasError: false };
static getDerivedStateFromError(error: Error): State {
return { hasError: true, error };
}
reset = () => {
this.props.onReset?.();
this.setState({ hasError: false, error: undefined });
};
render() {
if (this.state.hasError) {
return (
<div role="alert" className="p-6 text-center">
<h2 className="text-xl font-bold">Oops!</h2>
<p className="text-gray-600 mt-2">{this.state.error?.message}</p>
<button
onClick={this.reset}
className="mt-4 px-4 py-2 bg-blue-600 text-white rounded"
>
Try again
</button>
</div>
);
}
return this.props.children;
}
}react-error-boundary Library
Prefer the react-error-boundary package for production apps: it provides reset keys, hooks, and a typed FallbackProps contract.
import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
return (
<div role="alert" className="p-4 bg-red-50 rounded-lg">
<p className="font-medium">Something went wrong:</p>
<pre className="text-sm text-red-600 mt-2">{error.message}</pre>
<button onClick={resetErrorBoundary} className="mt-4 btn-primary">
Try again
</button>
</div>
);
}
// Usage
function App() {
return (
<ErrorBoundary
FallbackComponent={ErrorFallback}
onReset={() => {
// Reset app state here
}}
onError={(error, info) => {
// Log to error reporting service
console.error(error, info);
}}
>
<MyComponent />
</ErrorBoundary>
);
}Next.js App Router Error Handling
The App Router uses file conventions to catch errors per route segment. Each file must be placed inside the relevant app/ segment.
Route Segment Error (app/error.tsx)
Catches errors thrown in the route segment and its children. Must be a Client Component.
// app/error.tsx (or any route segment)
'use client';
import { useEffect } from 'react';
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
useEffect(() => {
// Log error to reporting service
console.error(error);
}, [error]);
return (
<div className="flex flex-col items-center justify-center min-h-[400px]">
<h2 className="text-2xl font-bold">Something went wrong!</h2>
<button
onClick={reset}
className="mt-4 px-6 py-2 bg-blue-600 text-white rounded-lg"
>
Try again
</button>
</div>
);
}Global Error (app/global-error.tsx)
Catches errors in the root layout. Must render its own <html> and <body> because it replaces the root layout when active.
'use client';
export default function GlobalError({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
<html>
<body>
<div className="flex flex-col items-center justify-center min-h-screen">
<h2 className="text-2xl font-bold">Something went wrong!</h2>
<button onClick={reset} className="mt-4 btn-primary">
Try again
</button>
</div>
</body>
</html>
);
}Not Found (app/not-found.tsx)
Rendered when notFound() is called or for unmatched routes.
import Link from 'next/link';
export default function NotFound() {
return (
<div className="flex flex-col items-center justify-center min-h-[400px]">
<h2 className="text-4xl font-bold">404</h2>
<p className="text-gray-600 mt-2">Page not found</p>
<Link href="/" className="mt-4 text-blue-600 hover:underline">
Go home
</Link>
</div>
);
}