Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the right way to exit node.js script with a log message?

Tags:

node.js

I have a node.js script that does some logging to a file using WriteStream. On certain events I want to stop execution of the script, i.e. warn to log and exit immediately after that. Being asyncronious node.js does not allow us to do it straight forward like:

#!/usr/local/bin/node

var fs = require('fs');
var stream = fs.createWriteStream('delme.log', { flags: 'a' });

stream.write('Something bad happened\n');
process.exit(1);

Instead of appending a message to delme.log this script does nothing with the file. Handling 'exit' event and flushing doesn't work. The only way to write the last log message before exitting found so far is to wrap process.exit(1) in the setTimeout():

#!/usr/local/bin/node

var fs = require('fs');
var stream = fs.createWriteStream('delme.log', { flags: 'a' });

stream.write('Something bad happened\n');
setTimeout(function(){
  process.exit(1);
}, 30);

However in this form it doesn't stop the script execution immediately and the script will be running for some time after the critical event happened. So I'm wondering if there are other ways to exit a script with a log message?

like image 358
nab Avatar asked Feb 08 '12 10:02

nab


2 Answers

Since you want to block, and already are using a stream, you will probably want to handle the writing yourself.

var data = new Buffer('Something bad happened\n');
fs.writeSync(stream.fd, data, 0, data.length, stream.pos);
process.exit();
like image 156
fent Avatar answered Sep 29 '22 14:09

fent


Improved.

var fs = require('fs');
var stream = fs.createWriteStream('delme.log', {flags: 'a'});

// Gracefully close log
process.on('uncaughtException', function () {
    stream.write('\n'); // Make sure drain event will fire (queue may be empty!)
    stream.on('drain', function() {
        process.exit(1);
    });
});

// Any code goes here...
stream.write('Something bad happened\n');
throw new Error(SOMETHING_BAD);

The try-catch block works but it is ugly. Still, credits go @nab, I just prettified it.

like image 20
zupa Avatar answered Sep 29 '22 13:09

zupa