node.js fs.createWriteStream создает файл, но не может быть записан без ошибок

Я пытаюсь поймать Uncaught Exception и записать их в файл на сервере. Мой код:

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)).

1 ответ

Решение

Я обнаружил, что на самом деле я ловил 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)).

Что я могу попросить вас попробовать,

может быть, вы перехватываете неперехваченные исключения более одного раза, что может быть причиной того, что предыдущий метод умер, прежде чем записать ошибку в файл.

возобновлять нормальную работу после "uncaught Exception" небезопасно, поскольку система повреждена. Правильное использование "uncaught Exception" заключается в выполнении синхронной очистки выделенных ресурсов (например, файловых дескрипторов, дескрипторов и т. Д.) Перед остановкой процесса.

Я настоятельно рекомендую вам прочитать это -> 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)
})`
Другие вопросы по тегам