const { logger } = require('../config/logger'); const { ERROR_CODES, HTTP_STATUS } = require('../config/constants'); // 全局错误处理中间件 const errorHandler = (err, req, res, next) => { let error = { ...err }; error.message = err.message; // 记录错误日志 logger.error('Error occurred:', { message: err.message, stack: err.stack, url: req.originalUrl, method: req.method, ip: req.ip, userAgent: req.get('User-Agent'), userId: req.user?.id }); // MySQL错误处理 if (err.code) { switch (err.code) { case 'ER_DUP_ENTRY': error.message = '数据已存在'; error.statusCode = HTTP_STATUS.CONFLICT; error.errorCode = ERROR_CODES.DUPLICATE_ENTRY; break; case 'ER_NO_REFERENCED_ROW_2': error.message = '关联数据不存在'; error.statusCode = HTTP_STATUS.BAD_REQUEST; error.errorCode = ERROR_CODES.VALIDATION_ERROR; break; case 'ER_ROW_IS_REFERENCED_2': error.message = '数据正在被使用,无法删除'; error.statusCode = HTTP_STATUS.CONFLICT; error.errorCode = ERROR_CODES.VALIDATION_ERROR; break; case 'ECONNREFUSED': error.message = '数据库连接失败'; error.statusCode = HTTP_STATUS.INTERNAL_SERVER_ERROR; error.errorCode = ERROR_CODES.DATABASE_ERROR; break; default: error.message = '数据库操作失败'; error.statusCode = HTTP_STATUS.INTERNAL_SERVER_ERROR; error.errorCode = ERROR_CODES.DATABASE_ERROR; } } // JWT错误处理 if (err.name === 'JsonWebTokenError') { error.message = '无效的访问令牌'; error.statusCode = HTTP_STATUS.UNAUTHORIZED; error.errorCode = ERROR_CODES.AUTHENTICATION_ERROR; } if (err.name === 'TokenExpiredError') { error.message = '访问令牌已过期'; error.statusCode = HTTP_STATUS.UNAUTHORIZED; error.errorCode = ERROR_CODES.AUTHENTICATION_ERROR; } // 参数验证错误 if (err.name === 'ValidationError' || err.isJoi) { const message = err.details ? err.details.map(detail => detail.message).join(', ') : err.message; error.message = `参数验证失败: ${message}`; error.statusCode = HTTP_STATUS.BAD_REQUEST; error.errorCode = ERROR_CODES.VALIDATION_ERROR; } // 业务逻辑错误处理 if (err.message === '余额不足') { error.message = '用户积分余额不足,无法完成转账操作。请先为用户充值积分或选择其他用户。'; error.statusCode = HTTP_STATUS.BAD_REQUEST; error.errorCode = ERROR_CODES.VALIDATION_ERROR; } if (err.message === '用户不存在') { error.message = '指定的用户不存在,请检查用户信息后重试。'; error.statusCode = HTTP_STATUS.BAD_REQUEST; error.errorCode = ERROR_CODES.VALIDATION_ERROR; } // 自定义错误 if (err.statusCode) { error.statusCode = err.statusCode; error.errorCode = err.errorCode || ERROR_CODES.INTERNAL_ERROR; } // 默认错误 const statusCode = error.statusCode || HTTP_STATUS.INTERNAL_SERVER_ERROR; const errorCode = error.errorCode || ERROR_CODES.INTERNAL_ERROR; const message = error.message || '服务器内部错误'; res.status(statusCode).json({ success: false, error: { code: errorCode, message: message }, ...(process.env.NODE_ENV === 'development' && { stack: err.stack }) }); }; // 404错误处理 const notFound = (req, res, next) => { const error = new Error(`路径 ${req.originalUrl} 未找到`); error.statusCode = HTTP_STATUS.NOT_FOUND; error.errorCode = ERROR_CODES.NOT_FOUND; next(error); }; // 自定义错误类 class AppError extends Error { constructor(message, statusCode, errorCode) { super(message); this.statusCode = statusCode; this.errorCode = errorCode; this.isOperational = true; Error.captureStackTrace(this, this.constructor); } } module.exports = { errorHandler, notFound, AppError };