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

Express+Winston+Events配置异常:报错时日志无法写入文件

问题原因及修复方案

你的代码里错误日志无法写入文件的核心原因是:

  • handleDoSomethingHeavy是异步函数,它抛出的错误属于未处理的Promise拒绝,而Winston的handleExceptions配置仅负责捕获同步代码中未捕获的异常,对异步Promise的未处理拒绝无效。
  • 你通过setImmediate调用异步函数时,没有捕获其抛出的错误,也没有主动调用Winston的日志方法来记录这个错误,导致只有Node.js默认的控制台错误输出,没有触发Winston的文件传输器。

具体修复方式

方式一:在异步函数内部捕获错误并记录

修改handleDoSomethingHeavy函数,用try/catch捕获错误,主动调用logger.error记录:

async function handleDoSomethingHeavy(payload) {
  try {
    console.log('alok', payload)
    throw new Error('Something went wrong')
  } catch (err) {
    logger.error('处理任务时出错: %s', err.message, { stack: err.stack })
  }
}

方式二:在事件监听中处理异步函数的Promise拒绝

修改事件监听器,使用async/await配合try/catch捕获错误:

eventEmitter.on('doSomethingHeavy', async (payload) => {
  try {
    await handleDoSomethingHeavy(payload)
  } catch (err) {
    logger.error('处理任务时出错: %s', err.message, { stack: err.stack })
  }
});

额外:全局捕获未处理的Promise拒绝(可选)

如果想覆盖所有未被捕获的Promise拒绝,在代码中添加全局监听:

process.on('unhandledRejection', (reason, promise) => {
  logger.error('未处理的Promise拒绝: %s', reason.message, { stack: reason.stack, promise });
});

修改后的完整代码示例

const winston = require('winston');
const express = require('express')
var events = require('events');

async function handleDoSomethingHeavy(payload) {
  console.log('alok', payload)
  throw new Error('Something went wrong')
}

var eventEmitter = new events.EventEmitter();
// 修改事件监听器,处理异步错误
eventEmitter.on('doSomethingHeavy', async (payload) => {
  try {
    await handleDoSomethingHeavy(payload)
  } catch (err) {
    logger.error('处理任务时出错: %s', err.message, { stack: err.stack })
  }
});

const app = express()
const port = 3000

var options = {
  file: {
    level: 'debug',
    filename: `mylogs-${Date.now()}.log`,
    handleExceptions: true,
    format: winston.format.combine(
      winston.format.splat(),
      winston.format.timestamp(),
      winston.format.json() // 建议添加格式,让日志更易读
    ),
    maxsize: 100 * 1024 * 1024,
    maxFiles: 10,
  },
  console: {
    level: 'debug',
    handleExceptions: true,
    format: winston.format.combine(
      winston.format.splat(),
      winston.format.timestamp(),
      winston.format.colorize(),
      winston.format.simple()
    ),
  }
}

var logger = winston.createLogger({
  levels: winston.config.syslog.levels,
  transports: [
    new winston.transports.File(options.file),
    new winston.transports.Console(options.console)
  ],
  exitOnError: false,
})

// 全局监听未处理的Promise拒绝
process.on('unhandledRejection', (reason, promise) => {
  logger.error('未处理的Promise拒绝: %s', reason.message, { stack: reason.stack, promise });
});

app.get('/', (req, res) => {
  logger.info('Got get request')
  let payload = { name: 'Alok' }
  eventEmitter.emit('doSomethingHeavy', payload);
  res.send('Task queued')
})

app.listen(port, () => {
  logger.info(`Example app listening on port ${port}`)
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 06:47:27