- Home
- Skills
- Code Review
- Error Handling Review
Error Handling Review
Review error handling patterns: try/catch usage, error boundaries, user feedback, and graceful degradation.
The Problem
Error handling is the most neglected dimension of code quality. Developers wrap everything in try/catch and log to console — silently swallowing failures that should crash loudly. Network requests assume success. Form submissions show nothing when the API returns 500. Database operations lack retry logic. The result: users see blank screens, data corrupts silently, and debugging becomes forensic archaeology because errors were caught and discarded.
The Prompt
Review the error handling in the following code. Act as a reliability engineer evaluating how the system behaves when things go wrong.
LANGUAGE/FRAMEWORK: [e.g., TypeScript/React, Python/FastAPI, Go]
CONTEXT: [e.g., payment processing, user registration, file upload]
CODE:
[paste your code here]
Evaluate these error handling dimensions:
1. **Catch Quality**
- Are catch blocks too broad (catching Error instead of specific types)?
- Do catch blocks swallow errors silently (empty catch, console.log only)?
- Are errors re-thrown when they should bubble up?
- Is the original error preserved in wrapped exceptions (cause chaining)?
2. **User Communication**
- Does the user see a helpful message when something fails?
- Are error states designed, or does the UI just go blank?
- Are transient errors (network, timeout) distinguished from permanent ones?
- Is there a retry mechanism for recoverable failures?
3. **Boundary Protection**
- Are API responses validated before use?
- Do database operations have transaction rollback on failure?
- Are file operations wrapped with proper cleanup (finally blocks)?
- Do external service calls have timeouts configured?
4. **Error Propagation**
- Is the error propagation strategy consistent (throw vs return Result vs callback)?
- Can the caller distinguish between error types to decide recovery strategy?
- Are async errors handled (unhandled promise rejections)?
5. **Observability**
- Are errors logged with sufficient context (user ID, request ID, input data)?
- Are error rates monitored (not just logged)?
- Do structured logs enable filtering and alerting?
6. **Edge Cases**
- What happens with empty inputs, null values, or malformed data?
- Are race conditions handled (double submit, stale data)?
- Is there a global error boundary / unhandled rejection handler?
For each issue, provide:
- **Location**: File and line
- **Failure Mode**: What happens when this fails in production
- **Severity**: silent-failure / poor-ux / data-risk / crash
- **Fix**: Improved error handling code
Example Output
## Error Handling Review: 5 issues found
### Silent Failure: Swallowed Database Error
Location: src/services/user.ts:34
Code:
try { await db.insert(user); }
catch (e) { console.log('insert failed'); }
Failure Mode: User sees success message but data was never saved.
Fix:
try { await db.insert(user); }
catch (error) {
logger.error('User insert failed', { userId: user.id, error });
throw new DatabaseError('Failed to create user', { cause: error });
}
### Poor UX: Unhandled Loading State
Location: src/components/Dashboard.tsx:18
Code: `const { data } = useSWR('/api/stats')` — no error or loading handling.
Failure Mode: Component renders with undefined data, shows blank or crashes.
Fix:
const { data, error, isLoading } = useSWR('/api/stats');
if (isLoading) return <Skeleton />;
if (error) return <ErrorCard message="Failed to load dashboard" retry={mutate} />;
When to Use
Run this on code that handles user input, network requests, database operations, or payment processing — anywhere failure has consequences. Essential before production deployments and after any incident where “the error was caught but nobody noticed” was the root cause.
Pro Tips
- Test the unhappy path — after the review, ask “Generate test cases that exercise every error path in this code” to verify your error handling actually works.
- Ask for error taxonomy — request “Categorize all possible errors into recoverable (retry), user-fixable (show form errors), and fatal (show error page)” for a structured approach.
- Check error boundaries — in React apps, ask “Where should React Error Boundaries be placed to prevent the entire app from crashing?”