Back
📜Rulecursor
Full-Stack API Error Handler
A Copilot/Cursor rule for implementing consistent error handling across full-stack TypeScript applications. Covers HTTP errors, validation, and logging.
by TypeScriptGuru·6 days ago·
error handlingtypescriptapifull-stackbest practices
# Error Handling Rule
When implementing API endpoints, ALWAYS follow this error handling pattern:
## Server-side (Next.js Route Handlers / Express)
```typescript
import { AppError, ValidationError, NotFoundError, AuthError } from '@/lib/errors';
// Use typed error classes
try {
const data = await operation();
return Response.json({ data });
} catch (error) {
if (error instanceof ValidationError) {
return Response.json({ error: error.message, details: error.fields }, { status: 400 });
}
if (error instanceof NotFoundError) {
return Response.json({ error: error.message }, { status: 404 });
}
if (error instanceof AuthError) {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
}
// Log unexpected errors, don't expose internals
console.error('Unexpected error:', error);
return Response.json({ error: 'Internal server error' }, { status: 500 });
}
```
## Client-side
```typescript
// Always handle loading, error, and success states
const [state, setState] = useState<{ data: T | null; error: string | null; loading: boolean }>({
data: null, error: null, loading: false
});
// Use try/catch with fetch
try {
setState(s => ({ ...s, loading: true, error: null }));
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
setState({ data, error: null, loading: false });
} catch (err) {
setState({ data: null, error: err instanceof Error ? err.message : 'Unknown error', loading: false });
}
```
NEVER: swallow errors silently, expose stack traces to clients, use any for error types.