如何在 node.js 进程错误事件上记录堆栈跟踪

Jef*_*eff 2 error-handling node.js

我的节点进程快要死了,我似乎无法在进程退出时登录到文件。这是一个长时间运行的进程,直接调用node index.js

// index.js
const fs = require('fs');

exports.getAllCars = (process => {
    if (require.main === module) {
        console.log(`Running process: ${process.getgid()}.`);
        let out = fs.createWriteStream(`${__dirname}/process.log`);

        // trying to handle process events here:
        process.on('exit', code => out.write(`Exit: ${code}`));

        return require('./lib/cars').getAllCars();
    } else {
        return require('./lib/cars').getAllCars;
    }
})(process);
Run Code Online (Sandbox Code Playgroud)

还尝试为error,创建事件处理程序uncaughtException。手动终止我的进程时没有任何作用(使用kill {pid})。该文件process.log已创建,但没有任何内容。可写流是否需要stream.end()在完成时调用?

Val*_*era 6

根据 Node.js 文档:

当 Node.js 进程由于以下任一原因即将退出时,将发出 'exit' 事件:

  • process.exit()显式调用的方法。
  • Node.js 事件循环不再需要执行任何额外的工作。

所以,如果你开始一个不应该结束的过程,它就永远不会触发。

此外,可写流不需要关闭:

如果autoClose(来自 的选项)在错误或结束时createWriteStream设置为true(默认行为),文件描述符将自动关闭。

但是,该createWriteStream函数'w'默认打开带有标志的文件,这意味着该文件每次都会被覆盖(也许这就是您总是看到它为空的原因)。我建议使用

fs.appendFileSync(file, data)
Run Code Online (Sandbox Code Playgroud)

以下是想要收听的事件:

//catches ctrl+c event
//NOTE:
//If SIGINT has a listener installed, its default behavior will be removed (Node.js will no longer exit).
process.on('SIGINT', () => {
    fs.appendFileSync(`${__dirname}/process.log`, `Received SIGINT\n`);
    process.exit()
});

//emitted when an uncaught JavaScript exception bubbles
process.on('uncaughtException', (err) => {
    fs.appendFileSync(`${__dirname}/process.log`, `Caught exception: ${err}\n`);
});

//emitted whenever a Promise is rejected and no error handler is attached to it
process.on('unhandledRejection', (reason, p) => {
    fs.appendFileSync(`${__dirname}/process.log`, `Unhandled Rejection at: ${p}, reason: ${reason}\n`);
});
Run Code Online (Sandbox Code Playgroud)