Error Handling Patterns
Robust error handling for production applications.
Instructions
- Custom Error Classes
class AppError extends Error { constructor( public message: string, public statusCode: number = 500, public code?: string ) { super(message); this.name = 'AppError'; Error.captureStackTrace(this, this.constructor); } }
class NotFoundError extends AppError {
constructor(resource: string) {
super(${resource} not found, 404, 'NOT_FOUND');
}
}
class ValidationError extends AppError { constructor(message: string) { super(message, 400, 'VALIDATION_ERROR'); } }
- Async Error Handling
// ✅ Async/await with try-catch
async function fetchUser(id: string) {
try {
const response = await api.get(/users/${id});
return response.data;
} catch (error) {
if (error instanceof AxiosError) {
throw new AppError(error.message, error.response?.status);
}
throw error;
}
}
// ✅ Promise error handling fetchUser(id) .then(handleSuccess) .catch(handleError);
- Express Error Middleware
// Error handler middleware app.use((err: Error, req: Request, res: Response, next: NextFunction) => { console.error(err.stack);
if (err instanceof AppError) { return res.status(err.statusCode).json({ success: false, error: { message: err.message, code: err.code } }); }
res.status(500).json({ success: false, error: { message: 'Internal server error', code: 'INTERNAL_ERROR' } }); });
- React Error Boundaries
class ErrorBoundary extends React.Component<Props, State> { state = { hasError: false, error: null };
static getDerivedStateFromError(error: Error) { return { hasError: true, error }; }
componentDidCatch(error: Error, errorInfo: ErrorInfo) { console.error('Error caught:', error, errorInfo); // Log to error reporting service }
render() { if (this.state.hasError) { return <ErrorFallback error={this.state.error} />; } return this.props.children; } }
- API Error Response Format
// Standard error response interface ApiError { success: false; error: { message: string; code: string; details?: unknown; }; }
// Example response { "success": false, "error": { "message": "User not found", "code": "USER_NOT_FOUND" } }
- Logging
import winston from 'winston';
const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [ new winston.transports.File({ filename: 'error.log', level: 'error' }), new winston.transports.File({ filename: 'combined.log' }) ] });
// Usage logger.error('Database connection failed', { error, context });
References
-
Node.js Error Handling
-
React Error Boundaries