node.jscreatewritestream

node.js fs.createWriteStream creates the file, but cannot be written to with no error


I am attempting to catch 'Uncaught Exception's and write them to a file on the server. My code is:

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();
        });
    });
}

The registerUser event is not my full event, but shortened just to throw an error.

Original

The console log at the bottom is printed to the command line (the caught exception line). The error file is created (if not already). However, nothing inside of the _error.write area is executed. No console logs are displayed, and the file remains empty.

It is not a permissions issue, as I have given everyone (666) access to read and write to the file (for testing). So I am not sure why this is not working. All of the examples I've seen show that this works for them. I am not sure why it does not work for me.

EDIT

Here is what I am seeing in the console:

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

RESOLVED

I found that I was actually catching uncaughtExceptions twice...

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);
    });

This was causing the previous method to die before it could actually write the error to the file (due to process.exit(1)).


Solution

  • I found that I was actually catching uncaughtExceptions twice...

    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);
        });
    

    This was causing the previous method to die before it could actually write the error to the file (due to process.exit(1)).