Spaces:
Paused
Paused
Download Middleware/errorHandler.js from imkrish/campverse-backend: direct link, hf CLI and curl.
- Browser
- Download file 5.43 kB
-
https://huggingface.co/spaces/imkrish/campverse-backend/resolve/main/Middleware/errorHandler.js
- Command line
-
hf download hf://spaces/imkrish/campverse-backend/Middleware/errorHandler.js
-
curl -L -o errorHandler.js https://huggingface.co/spaces/imkrish/campverse-backend/resolve/main/Middleware/errorHandler.js
5.43 kB
| const winston = require('winston'); | |
| const { | |
| isOperationalError, | |
| isDatabaseError, | |
| } = require('../Utils/errors'); | |
| // Configure logger | |
| const logger = winston.createLogger({ | |
| level: process.env.LOG_LEVEL || 'info', | |
| format: winston.format.combine( | |
| winston.format.timestamp(), | |
| winston.format.errors({ stack: true }), | |
| winston.format.json() | |
| ), | |
| defaultMeta: { service: 'campverse-backend' }, | |
| transports: [ | |
| new winston.transports.Console({ | |
| format: winston.format.combine( | |
| winston.format.colorize(), | |
| winston.format.simple() | |
| ) | |
| }) | |
| ] | |
| }); | |
| // Add file transport for production | |
| if (process.env.NODE_ENV === 'production') { | |
| logger.add(new winston.transports.File({ | |
| filename: 'logs/error.log', | |
| level: 'error' | |
| })); | |
| logger.add(new winston.transports.File({ | |
| filename: 'logs/combined.log' | |
| })); | |
| } | |
| // Enhanced error handling middleware | |
| function errorHandler(err, req, res, _next) { | |
| // Generate correlation ID for request tracking | |
| const correlationId = req.correlationId || generateCorrelationId(); | |
| // Log error with context | |
| const errorContext = { | |
| correlationId, | |
| method: req.method, | |
| url: req.url, | |
| userAgent: req.get('User-Agent'), | |
| ip: req.ip, | |
| userId: req.user?.id, | |
| timestamp: new Date().toISOString(), | |
| error: { | |
| name: err.name, | |
| message: err.message, | |
| stack: err.stack, | |
| statusCode: err.statusCode | |
| } | |
| }; | |
| // Handle different error types | |
| let statusCode = 500; | |
| let message = 'Internal Server Error'; | |
| let details = null; | |
| if (isOperationalError(err)) { | |
| // Operational errors (expected) | |
| statusCode = err.statusCode; | |
| message = err.message; | |
| details = err.details; | |
| // Log as warning for client errors, error for server errors | |
| if (statusCode >= 500) { | |
| logger.error('Operational Error', errorContext); | |
| } else { | |
| logger.warn('Client Error', errorContext); | |
| } | |
| } else if (isDatabaseError(err)) { | |
| // Database errors | |
| statusCode = 500; | |
| message = 'Database operation failed'; | |
| // Handle specific MongoDB errors | |
| if (err.code === 11000) { | |
| statusCode = 409; | |
| message = 'Resource already exists'; | |
| const field = Object.keys(err.keyPattern || {})[0]; | |
| details = { field, message: `Duplicate value for ${field}` }; | |
| } else if (err.name === 'CastError') { | |
| statusCode = 400; | |
| message = 'Invalid ID format'; | |
| details = { field: err.path, value: err.value }; | |
| } else if (err.name === 'ValidationError') { | |
| statusCode = 400; | |
| message = 'Validation failed'; | |
| details = Object.values(err.errors).map(e => ({ | |
| field: e.path, | |
| message: e.message, | |
| value: e.value | |
| })); | |
| } | |
| logger.error('Database Error', errorContext); | |
| } else if (err.name === 'JsonWebTokenError') { | |
| // JWT errors | |
| statusCode = 401; | |
| message = 'Invalid token'; | |
| logger.warn('JWT Error', errorContext); | |
| } else if (err.name === 'TokenExpiredError') { | |
| statusCode = 401; | |
| message = 'Token expired'; | |
| logger.warn('Token Expired', errorContext); | |
| } else if (err.name === 'MulterError') { | |
| // File upload errors | |
| statusCode = 400; | |
| message = 'File upload error'; | |
| if (err.code === 'LIMIT_FILE_SIZE') { | |
| message = 'File too large'; | |
| } else if (err.code === 'LIMIT_FILE_COUNT') { | |
| message = 'Too many files'; | |
| } | |
| logger.warn('File Upload Error', errorContext); | |
| } else { | |
| // Unexpected errors | |
| logger.error('Unexpected Error', errorContext); | |
| // In production, don't expose internal error details | |
| if (process.env.NODE_ENV === 'production') { | |
| message = 'Something went wrong'; | |
| } else { | |
| message = err.message; | |
| details = { stack: err.stack }; | |
| } | |
| } | |
| // Send error response | |
| const errorResponse = { | |
| success: false, | |
| error: message, | |
| correlationId, | |
| timestamp: new Date().toISOString() | |
| }; | |
| // Add details in development or for operational errors | |
| if (details && (process.env.NODE_ENV !== 'production' || isOperationalError(err))) { | |
| errorResponse.details = details; | |
| } | |
| // Add stack trace in development | |
| if (process.env.NODE_ENV === 'development' && err.stack) { | |
| errorResponse.stack = err.stack; | |
| } | |
| res.status(statusCode).json(errorResponse); | |
| } | |
| // Generate correlation ID for request tracking | |
| function generateCorrelationId() { | |
| return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; | |
| } | |
| // Middleware to add correlation ID to requests | |
| function addCorrelationId(req, res, next) { | |
| req.correlationId = req.get('X-Correlation-ID') || generateCorrelationId(); | |
| res.set('X-Correlation-ID', req.correlationId); | |
| next(); | |
| } | |
| // Async error wrapper for route handlers | |
| function asyncHandler(fn) { | |
| return (req, res, next) => { | |
| Promise.resolve(fn(req, res, next)).catch(next); | |
| }; | |
| } | |
| // Handle unhandled promise rejections | |
| process.on('unhandledRejection', (reason, promise) => { | |
| logger.error('Unhandled Rejection', { | |
| reason: reason.toString(), | |
| stack: reason.stack, | |
| promise | |
| }); | |
| // Graceful shutdown | |
| process.exit(1); | |
| }); | |
| // Handle uncaught exceptions | |
| process.on('uncaughtException', (error) => { | |
| logger.error('Uncaught Exception', { | |
| error: error.message, | |
| stack: error.stack | |
| }); | |
| // Graceful shutdown | |
| process.exit(1); | |
| }); | |
| module.exports = { | |
| errorHandler, | |
| addCorrelationId, | |
| asyncHandler, | |
| logger | |
| }; | |