Error Handling
Rationale
Consistent error handling improves reliability, debugging, and user experience. It helps prevent silent failures and makes troubleshooting easier.
Centralized Error Handling
Use a centralized approach for handling errors. Create error handler functions or modules to manage exceptions and log errors consistently.
Example (Node.js Express):
app.use((err, req, res, next) => {
// Log error
console.error(err);
// Send user-friendly message
res.status(500).json({ error: 'Internal server error' });
});
Example (Browser):
window.onerror = function(message, source, lineno, colno, error) {
// Log error to monitoring service
sendErrorToService({ message, source, lineno, colno });
};
Custom Errors
Define custom error classes for specific error types to improve clarity and debugging.
Example:
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = 'ValidationError';
}
}
throw new ValidationError('Email is invalid');
Logging
Log errors and important events using a logging library or custom logger. Avoid exposing sensitive information in error messages.
Example:
// Good: Use a logging library
import winston from 'winston';
const logger = winston.createLogger({ /* ... */ });
logger.error('Something went wrong', error);
// Bad: Use console.log for errors in production
console.log('Error:', error);
- Avoid logging sensitive data.
- Use external monitoring tools (Sentry, Loggly) for production.
User-Friendly Error Messages
- Display clear, actionable error messages to users.
- Avoid technical jargon and stack traces in user-facing errors.
Example:
try { // ... } catch (e) { showError('Something went wrong. Please try again.'); }
Best Practices
- Return user-friendly error messages.
- Test error handling in both development and production environments.
- Use custom error pages or dialogs for common errors (404, 500).
- Document error handling conventions for new team members.
- Monitor logs and set up alerts for critical errors.