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

如何用Winston Logger记录Node.js错误?未捕获ReferenceError排查

解决Winston未捕获Node.js运行时全局错误的问题

这个问题我之前也碰到过——Winston默认并不会自动帮你捕获Node.js的全局未处理错误,你的自定义log方法只是主动调用时才会生效,那些跑出代码之外的运行时错误(比如你遇到的ReferenceError: totalValue is not defined)根本没机会触发你的log函数,所以才会出现应用冻结却没日志的情况。

要解决这个问题,你需要手动监听Node.js的两个全局事件,把这些未捕获的错误路由到Winston的日志系统里:

1. 先确认你的Winston Logger配置正确

首先确保你已经创建了一个配置好输出目标(比如文件、控制台)的Winston实例,比如:

const winston = require('winston');

// 创建Winston logger实例
const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    // 输出错误到文件
    new winston.transports.File({ filename: 'errors.log', level: 'error' }),
    // 同时输出到控制台方便调试
    new winston.transports.Console({ format: winston.format.simple() })
  ]
});

// 你的自定义log方法(假设是挂载到全局)
global.log = (message) => {
  logger.info(message);
};

2. 监听uncaughtException捕获同步未处理错误

Node.js在遇到未被try/catch捕获的同步错误时,会触发uncaughtException事件,如果不监听这个事件,应用会直接崩溃且不会留下任何日志(除非你用了内置的默认处理,但默认处理也不会写入你的Winston日志)。

添加以下代码:

process.on('uncaughtException', (err) => {
  // 用Winston记录错误详情
  logger.error('【未捕获同步异常】', {
    error: err.message,
    stack: err.stack,
    timestamp: new Date().toISOString()
  });
  
  // 注意:发生uncaughtException后Node.js的状态可能不稳定,建议退出进程
  // 如果是生产环境,可以用PM2等进程管理器自动重启应用
  process.exit(1);
});

3. 监听unhandledRejection捕获Promise未处理拒绝

如果你的代码里有Promise被拒绝但没有用.catch()或者try/await/catch处理,Node.js会触发unhandledRejection事件,这个事件同样不会被Winston自动捕获,需要手动处理:

process.on('unhandledRejection', (reason, promise) => {
  logger.error('【未处理Promise拒绝】', {
    reason: reason instanceof Error ? reason.message : reason,
    stack: reason instanceof Error ? reason.stack : 'No stack trace available',
    promise: promise.toString(),
    timestamp: new Date().toISOString()
  });
  
  // 同样,建议退出进程以避免不稳定状态
  process.exit(1);
});

为什么要退出进程?

Node.js官方文档明确指出,在uncaughtException触发后,应用的内部状态可能已经损坏,继续运行可能导致内存泄漏、数据损坏等不可预测的问题。所以最佳实践是记录错误后立即退出,然后用进程管理器(比如PM2)自动重启应用。

额外提示

如果你的应用是基于Express、Koa等Web框架,除了全局事件监听,还要记得在框架层面处理路由错误(比如Express的error-handling middleware),确保请求处理过程中的错误也能被Winston捕获。

这样配置后,下次再出现类似ReferenceError的全局未处理错误时,Winston就会把错误详情写入日志文件,你也能及时发现问题所在,而不是面对一个静默冻结的应用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:13:08