node.js fs.createWriteStream 创建文件,但无法正确写入

Posted

技术标签:

【中文标题】node.js fs.createWriteStream 创建文件,但无法正确写入【英文标题】:node.js fs.createWriteStream creates the file, but cannot be written to with no error 【发布时间】:2018-12-02 03:29:44 【问题描述】:

我正在尝试捕获“未捕获的异常”并将它们写入服务器上的文件。我的代码是:

var cluster = require('cluster');
// The master's job to spawn workers initially and when they die

if (cluster.isMaster) 
    // Get the number of processor cores
    var cpuCount = require('os').cpus().length;

    // Create a worker for each CPU
    for (var i = 0; i < cpuCount; i += 1) 
        cluster.fork();
    

    // When a worker exits, fork a new one
    cluster.on('exit', function(worker) 
        console.log('Worker %d died', worker.id);
        cluster.fork();
    );
 else if (cluster.isWorker) 
    const _express = require('express');
    const _bodyParser = require('body-parser');
    const _cors = require('cors');
    const _fs = require('fs');
    const _util = require('util');
    const _app = _express();
    const _http = require('http');
    const _server = _http.createServer(_app);
    const _port = 80;

    process.on('uncaughtException', function(_err) 
        var _error = _fs.createWriteStream(__dirname + '/node.error.log',  flags: 'a' );

        _error.write(_err.message + '\n', (err) => 
            if (err) 
                console.log('Error:', err.message);
            else
                console.log('Error Written');
            
        );

        _error.end();

        console.log('Caught exception: ' + _err);
    );var _listener = _server.listen(_port, () => 
        console.log('Server started on port ' + _port);
    );

    const _io = require('socket.io')(_listener);

    // parse application/json
    _app.use(_bodyParser.json());

    // parse application/x-www-form-urlencoded
    _app.use(_bodyParser.urlencoded( extended: true ));

    _app.use(_express.static(__dirname + '/node_modules'));

    // Allow cross-origin requests
    var corsOptions = 
        origin: function(_origin, _callback)
            _callback(null, _origin);
        ,
        credentials: true
    ;

    _app.use(_cors(corsOptions));

    // html render engine
    _app.engine('html', require('ejs').renderFile);
    _app.set('view engine', 'html');

    _io.on('connection', function (_socket) 
        // Sends to the initiator
        _socket.emit("connectionSuccessful", "Connected on socket " + _socket.id);

        _socket.on('registerUser', function(_args) 
            console.log('registerUser', _args);
            fakeFunction();
        );
    );

registerUser 事件不是我的完整事件,只是为了抛出错误而缩短了。

原创

底部的控制台日志打印到命令行(caught exception 行)。错误文件已创建(如果尚未创建)。但是,_error.write 区域内的任何内容都不会执行。不显示控制台日志,文件保持为空。

这不是权限问题,因为我已授予每个人 (666) 读取和写入文件的权限(用于测试)。所以我不确定为什么这不起作用。我见过的所有例子都表明这对他们有用。我不确定为什么它对我不起作用。

编辑

这是我在控制台中看到的:

Server started on port 80
Connected
Caught exception: TypeError: Cannot read property 'multi_id' of undefined
TypeError: Cannot read property 'multi_id' of undefined
    at Query._callback (/var/www/nodejs/models/auctions.js:41:18)
    at Query.Sequence.end (/var/www/nodejs/node_modules/mysql-clusterfarm/lib/protocol/sequences/Sequence.js:85:24)
    at Query._handleFinalResultPacket (/var/www/nodejs/node_modules/mysql-clusterfarm/lib/protocol/sequences/Query.js:144:8)
    at Query.EofPacket (/var/www/nodejs/node_modules/mysql-clusterfarm/lib/protocol/sequences/Query.js:128:8)
    at Protocol._parsePacket (/var/www/nodejs/node_modules/mysql-clusterfarm/lib/protocol/Protocol.js:280:23)
    at Parser.write (/var/www/nodejs/node_modules/mysql-clusterfarm/lib/protocol/Parser.js:74:12)
    at Protocol.write (/var/www/nodejs/node_modules/mysql-clusterfarm/lib/protocol/Protocol.js:39:16)
    at Socket.<anonymous> (/var/www/nodejs/node_modules/mysql-clusterfarm/lib/Connection.js:109:28)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7) 'Uncaught Exception thrown'
Worker 1 died

已解决

我发现我实际上捕获了两次 uncaughtExceptions...

process
    .on('unhandledRejection', (reason, p) => 
        console.error(reason, 'Unhandled Rejection at Promise', p);
        console.log(reason, 'Unhandled Rejection at Promise', p);
        process.exit(1);
    )
    .on('uncaughtException', _err => 
        console.error(_err, 'Uncaught Exception thrown');
        console.log(_err, 'Uncaught Exception thrown');
        process.exit(1);
    );

这导致之前的方法在将错误实际写入文件之前就死掉了(由于process.exit(1))。

【问题讨论】:

您使用的是哪个节点版本?因为那个 sn-p 对我有用。 @MarcosCasagrande 它是 v8.11.3 奇怪,我用的是8.9 @MarcosCasagrande 是的,我完全不明白。即使从去年开始,也有很多示例使用此代码(基本上)。但它只是没有为我写任何东西。 似乎无法触发worker died,您能否提供一个触发它的sn-p,而不需要服务器或socket.io,一个我可以在没有的情况下运行的sn-p依赖关系,因为这些依赖关系不是这里的问题。 【参考方案1】:

我可以要求你尝试的是,

也许你不止一次地捕捉到未捕获的异常,这可能是上一个方法在实际将错误写入文件之前死掉的原因。

在“uncaughtException”之后恢复正常操作是不安全的,因为系统已损坏。 'uncaughtException' 的正确用法是在关闭进程之前对分配的资源(例如文件描述符、句柄等)执行同步清理。

我强烈建议您阅读此内容-> https://www.joyent.com/node-js/production/design/errors

可以看这个例子

 var cluster = require('cluster');
 var numCPUs = require('os').cpus().length;
 if (cluster.isMaster) 
 for (var i = 0; i < numCPUs; ++i) 
 cluster.fork();
  
cluster.on('exit', (worker, code, signal) => 
console.log('worker $worker.process.pid died');
cluster.fork();
);
 else 
var http = require('http');
var httpServer = http.createServer(app).listen(httpPort, function () 
console.log('process id local', process.pid)
console.log("http server started at port " + httpPort);
);

process.on('uncaughtException', function (err) 
console.error((new Date).toUTCString() + ' uncaughtException:', err.message)
console.error(err.stack)
process.exit(1)
)`

【讨论】:

【参考方案2】:

我发现我实际上捕获了两次 uncaughtExceptions...

process
    .on('unhandledRejection', (reason, p) => 
        console.error(reason, 'Unhandled Rejection at Promise', p);
        console.log(reason, 'Unhandled Rejection at Promise', p);
        process.exit(1);
    )
    .on('uncaughtException', _err => 
        console.error(_err, 'Uncaught Exception thrown');
        console.log(_err, 'Uncaught Exception thrown');
        process.exit(1);
    );

这导致之前的方法在将错误实际写入文件之前就死掉了(由于process.exit(1))。

【讨论】:

以上是关于node.js fs.createWriteStream 创建文件,但无法正确写入的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 模块

[Node.js]如何在IDEA中配置Node.js

node.js 初识node.js,运行在服务端的 JavaScript

node.js教程基础:node.js命令行选项

Node.js HTTP模块

Node.js基础:第一篇