← 返回首页

Node.js 后端错误处理与日志规范

2026-05-18 · Node.js

为什么需要规范的错误处理

刚入门的 Node.js 项目往往用 try-catch 满天飞,每个接口里都套一层,代码臃肿不说,处理方式也不统一——有的返回 500,有的返回自定义错误码,排查问题时简直噩梦。

建立一套全局统一的错误处理机制后,接口层的代码量能降一半以上,而且排查效率明显提高。

自定义错误类

先定义一个继承 Error 的业务错误类,方便区分不同类型的异常:

class AppError extends Error {
  constructor(message, statusCode, code) {
    super(message)
    this.statusCode = statusCode
    this.code = code
    this.isOperational = true
  }
}

// 使用
throw new AppError('用户不存在', 404, 'USER_NOT_FOUND')

全局错误中间件

Express 的错误中间件放在所有路由之后,统一捕获错误:

// 放在 router 注册之后
app.use((err, req, res, next) => {
  const statusCode = err.statusCode || 500
  const message = err.isOperational ? err.message : '服务器内部错误'

  console.error(`[${new Date().toISOString()}] ${err.stack}`)

  res.status(statusCode).json({
    success: false,
    code: err.code || 'INTERNAL_ERROR',
    message
  })
})

异步错误的处理

Express 4 默认不捕获 promise 中的异常,需要包装一下:

// utils/catchAsync.js
module.exports = (fn) => (req, res, next) => {
  Promise.resolve(fn(req, res, next)).catch(next)
}

// 路由中使用
router.get('/users', catchAsync(async (req, res) => {
  const users = await User.findAll()
  res.json({ success: true, data: users })
}))

PM2 日志管理

生产环境用 PM2 管理进程,日志自动写入文件。建议配置日志轮转:

// 安装 pm2-logrotate
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 30

小结

  1. 自定义 AppError 区分业务错误和系统错误
  2. 全局错误中间件统一处理,保证接口返回格式一致
  3. 用 catchAsync 包装异步路由,避免手动 try-catch
  4. 生产环境结合 PM2 logrotate 管理日志文件