You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express.js处理未捕获Node异常的最佳实践及优雅方案咨询

解决Express.js未捕获异常导致服务器崩溃的优雅方案

1. 配置全局错误处理中间件

Express原生支持全局错误处理机制,只需在所有路由和普通中间件之后定义一个带4个参数的中间件,就能捕获通过next(err)传递的错误。但要注意:异步路由/处理器内的异常不会被Express自动捕获,需要配合异步封装逻辑解决。

示例代码:

// 必须放在所有路由、中间件定义之后
app.use((err, req, res, next) => {
  console.error('服务器错误详情:', err.stack);
  // 区分开发/生产环境返回不同内容
  const statusCode = err.statusCode || 500;
  res.status(statusCode).json({
    message: process.env.NODE_ENV === 'production' ? '服务器内部错误' : err.message,
    error: process.env.NODE_ENV === 'production' ? {} : err.stack
  });
});

2. 封装异步路由处理器,自动捕获异常

不用每个路由都手动写try/catch或.catch(),写一个高阶函数统一处理异步函数的异常,自动将错误传递给next(err):

// 异步路由封装函数
const wrapAsync = (fn) => {
  return (req, res, next) => {
    // 自动捕获异步函数的异常并传给全局错误中间件
    fn(req, res, next).catch(next);
  };
};

// 使用示例
app.get('/api/user', wrapAsync(async (req, res) => {
  // 这里的异步操作异常会被自动捕获
  const user = await getUserById(req.params.id);
  res.json(user);
}));

所有通过wrapAsync包裹的异步路由,内部异常都会被自动捕获,不会导致服务器崩溃。

3. 捕获全局未捕获异常与未处理Promise拒绝

针对路由外的异常(比如启动阶段错误、非路由逻辑的异常),需要监听Node.js的全局事件,但要注意:uncaughtException触发后Node.js状态可能不稳定,处理完建议优雅退出并通过进程管理器重启。

示例代码:

// 处理未捕获的同步异常
process.on('uncaughtException', (err) => {
  console.error('未捕获全局异常:', err);
  // 若有未完成的请求,尽量返回500后退出
  process.exit(1);
});

// 处理未处理的Promise拒绝
process.on('unhandledRejection', (reason, promise) => {
  console.error('未处理的Promise拒绝:', reason);
  process.exit(1);
});

4. 用进程管理器实现自动重启

即使做了上述处理,部分严重错误仍可能导致服务器不稳定,使用PM2这类进程管理器可在崩溃时自动重启,保证服务可用性:

# 全局安装PM2
npm install pm2 -g
# 启动Express应用
pm2 start app.js

PM2会自动监控进程状态,崩溃后立即重启,同时支持日志记录,方便后续排查问题。

内容的提问来源于stack exchange,提问作者blek__

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:56:19