pax_global_header00006660000000000000000000000064130377263660014527gustar00rootroot0000000000000052 comment=f9453b68b8168def79fa8350f294e2b757f64d75 node-death-1.1.0/000077500000000000000000000000001303772636600135365ustar00rootroot00000000000000node-death-1.1.0/.gitignore000066400000000000000000000000151303772636600155220ustar00rootroot00000000000000node_modules/node-death-1.1.0/CHANGELOG.md000066400000000000000000000010341303772636600153450ustar00rootroot000000000000001.1.0 / 2017-01-18 ------------------ - ability to remove listeners 1.0.0 / 2015-03-17 ------------------ - removed `homepage` field in `package.json` - small formatting changes 0.1.0 / 2013-02-18 ------------------ * Fixed bugs due to setting of `uncaughtException`. Closes #1 * Changed default of `uncaughtException` from `true` to `false`. * Removed aliases for `uncaughtException`. * Fixed bug that when a key is set to false, it's still caught. * Passed signal to callback. 0.0.1 / 2012-12-01 ------------------ * Initial release. node-death-1.1.0/LICENSE000066400000000000000000000021241303772636600145420ustar00rootroot00000000000000(The MIT License) Copyright (c) 2012, JP Richardson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. node-death-1.1.0/README.md000066400000000000000000000045341303772636600150230ustar00rootroot00000000000000Node.js - death ================ Gracefully cleanup when termination signals are sent to your process. Why? ---- Because adding clean up callbacks for `uncaughtException`, `SIGINT`, and `SIGTERM` is annoying. Ideally, you can use this package to put your cleanup code in one place and exit gracefully if you need to. Operating System Compatibility ------------------------------ It's only been tested on POSIX compatible systems. [Here's a nice discussion](https://github.com/joyent/node/issues/1553) on Windows signals, apparently, this has been fixed/mapped. Installation ------------ npm install death Example ------ ```js var ON_DEATH = require('death'); //this is intentionally ugly ON_DEATH(function(signal, err) { //clean up code here }) ``` Usage ----- By default, it sets the callback on `SIGINT`, `SIGQUIT`, and `SIGTERM`. ### Signals - **SIGINT**: Sent from CTRL-C - **SIGQUIT**: Sent from keyboard quit action. - **SIGTERM**: Sent from operating system `kill`. More discussion and detail: http://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html and http://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html and http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap11.html. AS they pertain to Node.js: http://dailyjs.com/2012/03/15/unix-node-signals/ #### Want to catch uncaughtException? No problem, do this: ```js var ON_DEATH = require('death')({uncaughtException: true}) ``` #### Want to know which signals are being caught? Do this: ```js var ON_DEATH = require('death')({debug: true}) ``` Your process will then log anytime it catches these signals. #### Want to catch SIGHUP? Be careful with this one though. Typically this is fired if your SSH connection dies, but can also be fired if the program is made a daemon. Do this: ```js var ON_DEATH = require('death')({SIGHUP: true}) ``` #### Why choose the ugly "ON_DEATH"? Name it whatever you want. I like `ON_DEATH` because it stands out like a sore thumb in my code. #### Want to remove event handlers? If you want to remove event handlers `ON_DEATH` returns a function for cleaning up after itself: ```js var ON_DEATH = require('death') var OFF_DEATH = ON_DEATH(function(signal, err) { //clean up code here }) // later on... OFF_DEATH(); ``` License ------- (MIT License) Copyright 2012, JP Richardson node-death-1.1.0/app.js000066400000000000000000000005021303772636600146510ustar00rootroot00000000000000var ON_DEATH = require('./lib/death')({debug: true}) //to kill this, call `kill -9 pid` process.stdin.resume() ON_DEATH(function(err) { if (!err) console.log('Caught foo') else console.error('We got an uncaught exception! ' + err) }) setTimeout(function() { throw new Error('stupid exception') }, 5000) node-death-1.1.0/lib/000077500000000000000000000000001303772636600143045ustar00rootroot00000000000000node-death-1.1.0/lib/death.js000066400000000000000000000027221303772636600157320ustar00rootroot00000000000000 var defaultConfig = { uncaughtException: false, SIGINT: true, SIGTERM: true, SIGQUIT: true } var DEBUG = false function ON_DEATH (callback) { var handlers = []; Object.keys(defaultConfig).forEach(function(key) { var val = defaultConfig[key] var handler = null; if (val) { if (DEBUG) { handler = function() { var args = Array.prototype.slice.call(arguments, 0) args.unshift(key) console.log('Trapped ' + key) callback.apply(null, args) }; process.on(key, handler) } else { handler = function() { var args = Array.prototype.slice.call(arguments, 0) args.unshift(key) callback.apply(null, args) } process.on(key, handler) } handlers.push([key, handler]) } }) return function OFF_DEATH() { handlers.forEach(function (args) { var key = args[0]; var handler = args[1]; process.removeListener(key, handler); }) } } module.exports = function (arg) { if (typeof arg === 'object') { if (arg['debug']) DEBUG = arg.debug if (arg['DEBUG']) DEBUG = arg.DEBUG delete arg.debug; delete arg.DEBUG; Object.keys(arg).forEach(function(key) { defaultConfig[key] = arg[key] }) if (DEBUG) console.log('ON_DEATH: debug mode enabled for pid [%d]', process.pid) return ON_DEATH } else if (typeof arg === 'function') { return ON_DEATH(arg) } } node-death-1.1.0/package.json000066400000000000000000000013421303772636600160240ustar00rootroot00000000000000{ "name": "death", "version": "1.1.0", "description": "Gracefully cleanup when termination signals are sent to your process.", "repository": { "type": "git", "url": "git@github.com:jprichardson/node-death.git" }, "keywords": [ "sigint", "sigterm", "sigkill", "sigquit", "exception", "kill", "terminate", "process", "clean" ], "author": "JP Richardson ", "licenses": [ { "type": "MIT", "url": "" } ], "dependencies": {}, "devDependencies": { "win-spawn": "~1.1.1", "autoresolve": "0.0.3", "testutil": "~0.4.0", "colors": "~0.6.0-1" }, "main": "./lib/death.js", "scripts": { "test": "mocha test" } } node-death-1.1.0/test/000077500000000000000000000000001303772636600145155ustar00rootroot00000000000000node-death-1.1.0/test/death.test.js000066400000000000000000000111411303772636600171140ustar00rootroot00000000000000var spawn = require('win-spawn') var P = require('autoresolve') var testutil = require('testutil') var colors = require('colors') /* global describe, it, T, EQ */ describe('death', function() { describe('default behavior', function() { it('should catch SIGINT, SIGTERM, and SIGQUIT and return 3', function(done) { var signals = [] var progPath = P('test/resources/default') var prog = spawn(progPath, []) //console.dir(prog) prog.stdout.on('data', function(data) { //console.log(colors.cyan(data.toString())) }) prog.stderr.on('data', function(data) { //console.error(colors.red(data.toString())) signals = signals.concat(data.toString().trim().split('\n')) }) prog.on('exit', function(code) { EQ (code, 3) //console.dir(signals) T (signals.indexOf('SIGQUIT') >= 0) T (signals.indexOf('SIGTERM') >= 0) T (signals.indexOf('SIGINT') >= 0) done() }) setTimeout(function() { prog.kill('SIGINT') process.kill(prog.pid, 'SIGTERM') prog.kill('SIGQUIT') }, 100) }) }) describe('other signal', function() { it('should catch SIGINT, SIGTERM, SIGQUIT, and SIGHUP and return 4', function(done) { var signals = [] var progPath = P('test/resources/sighup') var prog = spawn(progPath, []) //console.dir(prog) prog.stdout.on('data', function(data) { //console.log(colors.cyan(data.toString())) }) prog.stderr.on('data', function(data) { //console.error(colors.red(data.toString())) signals = signals.concat(data.toString().trim().split('\n')) }) prog.on('exit', function(code) { EQ (code, 4) //console.dir(signals) T (signals.indexOf('SIGQUIT') >= 0) T (signals.indexOf('SIGTERM') >= 0) T (signals.indexOf('SIGINT') >= 0) T (signals.indexOf('SIGHUP') >= 0) done() }) setTimeout(function() { prog.kill('SIGINT') process.kill(prog.pid, 'SIGTERM') prog.kill('SIGQUIT') prog.kill('SIGHUP') }, 100) }) }) describe('disable signal', function() { it('should catch SIGINT and SIGTERM', function(done) { var signals = [] var progPath = P('test/resources/disable') var prog = spawn(progPath, []) //console.dir(prog) prog.stdout.on('data', function(data) { //console.log(colors.cyan(data.toString())) }) prog.stderr.on('data', function(data) { //console.error(colors.red(data.toString())) signals = signals.concat(data.toString().trim().split('\n')) }) prog.on('exit', function(code) { T (signals.indexOf('SIGQUIT') < 0) T (signals.indexOf('SIGTERM') >= 0) T (signals.indexOf('SIGINT') >= 0) done() }) setTimeout(function() { prog.kill('SIGINT') prog.kill('SIGTERM') setTimeout(function() { prog.kill('SIGQUIT') //this actually kills it since we disabled it },10) }, 100) }) }) describe('uncaughException', function() { describe('> when set to true', function() { it('should catch uncaughtException', function(done) { var errData = '' var progPath = P('test/resources/uncaughtException-true') var prog = spawn(progPath, []) //console.dir(prog) prog.stdout.on('data', function(data) { //console.log(colors.cyan(data.toString())) }) prog.stderr.on('data', function(data) { //console.error(colors.red(data.toString())) errData += data.toString().trim() }) prog.on('exit', function(code) { EQ (code, 70) T (errData.indexOf('uncaughtException') >= 0) T (errData.indexOf('UNCAUGHT SELF') >= 0) done() }) }) }) describe('> when set to false', function() { it('should catch uncaughtException', function(done) { var errData = '' var progPath = P('test/resources/uncaughtException-false') var prog = spawn(progPath, []) //console.dir(prog) prog.stdout.on('data', function(data) { //console.log(colors.cyan(data.toString())) }) prog.stderr.on('data', function(data) { //console.error(colors.red(data.toString())) errData += data.toString().trim() }) prog.on('exit', function(code) { EQ (code, 1) T (errData.indexOf('CAUGHT: uncaughtException') < 0) T (errData.indexOf('UNCAUGHT SELF') >= 0) done() }) }) }) }) }) node-death-1.1.0/test/mocha.opts000066400000000000000000000000471303772636600165140ustar00rootroot00000000000000--reporter spec --ui bdd --timeout 2000node-death-1.1.0/test/resources/000077500000000000000000000000001303772636600165275ustar00rootroot00000000000000node-death-1.1.0/test/resources/default000077500000000000000000000004301303772636600200760ustar00rootroot00000000000000#!/usr/bin/env node var P = require('autoresolve') , ON_DEATH = require(P('lib/death')) var ret = 0x0 console.log('HI FROM PROGRAM') ON_DEATH(function(signal, err) { console.error(signal) ret += 1 }) setTimeout(function() { //twiddle thumbs process.exit(ret) }, 500)node-death-1.1.0/test/resources/disable000077500000000000000000000004571303772636600200660ustar00rootroot00000000000000#!/usr/bin/env node var P = require('autoresolve') , ON_DEATH = require(P('lib/death'))({SIGQUIT: false}) var ret = 0x0 console.log('HI FROM PROGRAM') ON_DEATH(function(signal, err) { console.error(signal) ret += 1 }) setTimeout(function() { //twiddle thumbls process.exit(ret) }, 30000) node-death-1.1.0/test/resources/sighup000077500000000000000000000004501303772636600177530ustar00rootroot00000000000000#!/usr/bin/env node var P = require('autoresolve') , ON_DEATH = require(P('lib/death'))({SIGHUP: true}) var ret = 0x0 console.log('HI FROM PROGRAM') ON_DEATH(function(signal, err) { console.error(signal) ret += 1 }) setTimeout(function() { //twiddle thumbs process.exit(ret) }, 500)node-death-1.1.0/test/resources/uncaughtException-false000077500000000000000000000005001303772636600232350ustar00rootroot00000000000000#!/usr/bin/env node var P = require('autoresolve') , ON_DEATH = require(P('lib/death'))({uncaughtException: false}) var ret = 0x0 console.log('HI FROM PROGRAM') ON_DEATH(function(signal, err) { console.error('CAUGHT: ' + signal) console.error(err.message) process.exit(70) }) throw new Error('UNCAUGHT SELF')node-death-1.1.0/test/resources/uncaughtException-true000077500000000000000000000004621303772636600231310ustar00rootroot00000000000000#!/usr/bin/env node var P = require('autoresolve') , ON_DEATH = require(P('lib/death'))({uncaughtException: true}) var ret = 0x0 console.log('HI FROM PROGRAM') ON_DEATH(function(signal, err) { console.error(signal) console.error(err.message) process.exit(70) }) throw new Error('UNCAUGHT SELF')