/** * 错误处理中间件 * * 功能: * 1. 捕获异步函数中的错误 * 2. 统一处理404错误 * 3. 统一处理所有错误 */ const { error: errorResponse } = require('../utils/response'); /** * 异步错误处理包装器 * @param {function} fn - 异步处理函数 * @returns {function} Express中间件函数 * * 说明:在async函数中如果出错,会自动被catch捕获并传递给错误处理中间件 * * 使用示例: * router.get('/users', asyncHandler(async (req, res) => { * const users = await User.findAll(); * res.json(users); * })); */ const asyncHandler = (fn) => { return (req, res, next) => { // 执行异步函数,如果出错就传递给next Promise.resolve(fn(req, res, next)).catch(next); }; }; /** * 404 Not Found 错误处理 * 当请求的路由不存在时调用 */ const notFound = (req, res, next) => { const error = new Error(`请求的资源不存在 - ${req.originalUrl}`); error.status = 404; next(error); // 将错误传递给下一个错误处理中间件 }; /** * 全局错误处理中间件 * 捕获所有错误并返回统一格式的响应 * * @param {Error} err - 错误对象 * @param {object} req - 请求对象 * @param {object} res - 响应对象 * @param {function} next - next函数 */ const errorHandler = (err, req, res, next) => { // 确定HTTP状态码 const statusCode = err.status || err.statusCode || 500; // 记录错误日志 console.error('❌ 错误发生:'); console.error('时间:', new Date().toLocaleString()); console.error('路径:', req.method, req.originalUrl); console.error('错误信息:', err.message); // 在开发环境下打印错误堆栈 if (process.env.NODE_ENV === 'development') { console.error('错误堆栈:', err.stack); } // 返回错误响应 res.status(statusCode).json({ ...errorResponse(err.message, err.code), // 开发环境返回详细错误信息 ...(process.env.NODE_ENV === 'development' && { stack: err.stack, path: req.originalUrl }) }); }; /** * 自定义错误类 - 业务逻辑错误 * 用于主动抛出可预期的业务错误 * * 使用示例: * if (!user) { * throw new BusinessError('用户不存在', 404); * } */ class BusinessError extends Error { constructor(message, statusCode = 400, code = null) { super(message); this.statusCode = statusCode; this.code = code; this.name = 'BusinessError'; } } /** * 自定义错误类 - 验证错误 * 用于数据验证失败的情况 */ class ValidationError extends Error { constructor(message, errors = []) { super(message); this.statusCode = 400; this.errors = errors; // 详细的验证错误列表 this.name = 'ValidationError'; } } /** * 自定义错误类 - 认证错误 * 用于身份认证失败的情况 */ class AuthenticationError extends Error { constructor(message = '认证失败,请先登录') { super(message); this.statusCode = 401; this.name = 'AuthenticationError'; } } /** * 自定义错误类 - 授权错误 * 用于权限不足的情况 */ class AuthorizationError extends Error { constructor(message = '权限不足') { super(message); this.statusCode = 403; this.name = 'AuthorizationError'; } } // 导出所有函数和类 module.exports = { asyncHandler, notFound, errorHandler, BusinessError, ValidationError, AuthenticationError, AuthorizationError };