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

如何在PM2中实现捕获日志/异常后执行自定义代码再退出进程?

解决PM2环境下Node.js全局异常捕获失效问题

原生Node.js的uncaughtException监听在PM2环境失效的核心原因是PM2默认会拦截未捕获异常事件,并直接触发进程重启逻辑,业务代码的监听逻辑还没执行完进程就被销毁了,按照以下步骤调整即可正常生效:

步骤1:调整PM2配置

在你的PM2生态配置文件(通常为ecosystem.config.js)中添加以下配置,给业务代码预留足够的异常处理时间:

module.exports = {
  apps : [{
    name: "你的应用名称",
    script: "你的应用入口文件路径",
    // 给进程预留5秒的收尾时间,可根据日志写入耗时调整
    kill_timeout: 5000,
    // 如果需要处理完异常后自动重启进程,保留以下配置,不需要自动重启则设为false
    autorestart: true,
    // Cluster模式下需要额外添加以下配置,避免主进程拦截异常事件
    combine_logs: true,
    merge_logs: true
  }]
}

配置修改完成后执行pm2 reload ecosystem.config.js生效。

步骤2:调整异常监听代码

注意必须保证日志写入完成后再调用进程退出方法,不要使用异步写日志后直接退出的逻辑:

// 处理同步代码未捕获异常
process.on("uncaughtException", err => {
  // 优先使用同步方法写入日志,避免异步操作未完成进程就退出
  syncWriteErrorLog(err);
  // 如果必须用异步写日志,要在回调中执行退出
  // asyncWriteErrorLog(err, () => {
  //   process.exit(1);
  // });
  process.exit(1);
});

// 建议同时补充Promise未捕获异常的监听
process.on("unhandledRejection", (reason, promise) => {
  const err = new Error(`未捕获的Promise异常,promise:${promise},原因:${reason}`);
  syncWriteErrorLog(err);
  process.exit(1);
});

注意事项

  • 异常监听回调中仅执行日志上报、资源释放这类必要的轻量操作,不要执行复杂业务逻辑,避免触发二次异常
  • 如果不需要PM2自动重启进程,将autorestart配置设为false即可
  • 日志写入耗时较长的话可以适当调大kill_timeout的数值,单位为毫秒

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:24:01