const logger = require('../utils/logger'); // Error handling middleware const errorHandler = (err, req, res, next) => { let error = { ...err }; error.message = err.message; // Log error logger.error('Error occurred:', { message: err.message, stack: err.stack, url: req.url, method: req.method, ip: req.ip, userAgent: req.get('User-Agent') }); // Mongoose bad ObjectId if (err.name === 'CastError') { const message = 'Resource not found'; error = { message, statusCode: 404 }; } // Mongoose duplicate key if (err.code === 11000) { const message = 'Duplicate field value entered'; error = { message, statusCode: 400 }; } // Mongoose validation error if (err.name === 'ValidationError') { const message = Object.values(err.errors).map(val => val.message).join(', '); error = { message, statusCode: 400 }; } // JWT errors if (err.name === 'JsonWebTokenError') { const message = 'Invalid token'; error = { message, statusCode: 401 }; } if (err.name === 'TokenExpiredError') { const message = 'Token expired'; error = { message, statusCode: 401 }; } // MySQL errors if (err.code === 'ER_DUP_ENTRY') { const message = 'Duplicate entry found'; error = { message, statusCode: 400 }; } if (err.code === 'ER_NO_REFERENCED_ROW_2') { const message = 'Referenced record not found'; error = { message, statusCode: 400 }; } if (err.code === 'ER_ROW_IS_REFERENCED_2') { const message = 'Cannot delete record - it is referenced by other records'; error = { message, statusCode: 400 }; } // Redis errors if (err.code === 'ECONNREFUSED' && err.syscall === 'connect') { const message = 'Cache service unavailable'; error = { message, statusCode: 503 }; } // Network errors if (err.code === 'ENOTFOUND') { const message = 'Service not found'; error = { message, statusCode: 503 }; } if (err.code === 'ETIMEDOUT') { const message = 'Request timeout'; error = { message, statusCode: 408 }; } // Default error const statusCode = error.statusCode || 500; const message = error.message || 'Server Error'; // Don't leak error details in production const response = { success: false, error: message, ...(process.env.NODE_ENV === 'development' && { stack: err.stack }) }; res.status(statusCode).json(response); }; module.exports = errorHandler;