Research
Security News
Kill Switch Hidden in npm Packages Typosquatting Chalk and Chokidar
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
async-exit-hook
Advanced tools
Run some code when the process exits (supports async hooks and pm2 clustering)
The async-exit-hook npm package allows you to register asynchronous functions that will be called when the Node.js process is exiting. This is useful for cleanup tasks, such as closing database connections, saving state, or other asynchronous operations that need to be completed before the process exits.
Registering an asynchronous exit hook
This feature allows you to register an asynchronous function that will be called when the process is exiting. The function can perform any necessary cleanup tasks and must call the provided callback when done.
const exitHook = require('async-exit-hook');
exitHook(async (callback) => {
console.log('Process is exiting...');
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('Cleanup done.');
callback();
});
// Simulate process exit
die();
Registering multiple exit hooks
You can register multiple asynchronous exit hooks. Each hook will be called in the order they were registered, allowing for complex cleanup sequences.
const exitHook = require('async-exit-hook');
exitHook(async (callback) => {
console.log('First hook');
await new Promise(resolve => setTimeout(resolve, 500));
callback();
});
exitHook(async (callback) => {
console.log('Second hook');
await new Promise(resolve => setTimeout(resolve, 500));
callback();
});
// Simulate process exit
die();
Handling signals
The package can handle various signals (e.g., SIGINT, SIGTERM) and execute the registered hooks when such signals are received, ensuring proper cleanup before the process exits.
const exitHook = require('async-exit-hook');
exitHook(async (callback) => {
console.log('Received signal, cleaning up...');
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('Cleanup done.');
callback();
});
// Simulate receiving a signal
process.kill(process.pid, 'SIGINT');
The exit-hook package allows you to register synchronous functions to be called when the process exits. Unlike async-exit-hook, it does not support asynchronous operations, making it less suitable for tasks that require asynchronous cleanup.
The node-cleanup package provides a way to register cleanup handlers that are called when the process exits. It supports both synchronous and asynchronous cleanup functions, similar to async-exit-hook, but offers additional features like handling uncaught exceptions and unhandled promise rejections.
The signal-exit package allows you to execute a callback when the process exits or receives a termination signal. It supports both synchronous and asynchronous callbacks, similar to async-exit-hook, but focuses more on handling various exit signals and conditions.
Run some code when the process exits
The process.on('exit')
event doesn't catch all the ways a process can exit. This module catches:
Useful for cleaning up. You can also include async handlers, and add custom events to hook and exit on.
Forked and pretty much rewritten from exit-hook.
$ npm install --save async-exit-hook
process.exit()
and asynchronous codeIf you use asynchronous exit hooks, DO NOT use process.exit()
to exit.
The exit
event DOES NOT support asynchronous code.
['beforeExit' is not emitted for conditions causing explicit termination, such as process.exit()] (https://nodejs.org/api/process.html#process_event_beforeexit)
process.kill(signal)
On windows process.kill(signal)
immediately kills the process, and does not fire signal events,
and as such, cannot be used to gracefully exit. See Clustering and child processes for a
workaround when killing child processes. I'm planning to support gracefully exiting
with async support on windows soon.
If you use custom clustering / child processes, you can gracefully shutdown your child process
by sending a shutdown message (childProc.send('shutdown')
).
const exitHook = require('async-exit-hook');
exitHook(() => {
console.log('exiting');
});
// you can add multiple hooks, even across files
exitHook(() => {
console.log('exiting 2');
});
// you can add async hooks by accepting a callback
exitHook(callback => {
setTimeout(() => {
console.log('exiting 3');
callback();
}, 1000);
});
// You can hook uncaught errors with uncaughtExceptionHandler(), consequently adding
// async support to uncaught errors (normally uncaught errors result in a synchronous exit).
exitHook.uncaughtExceptionHandler(err => {
console.error(err);
});
// You can hook unhandled rejections with unhandledRejectionHandler()
exitHook.unhandledRejectionHandler(err => {
console.error(err);
});
// You can add multiple uncaught error handlers
// Add the second parameter (callback) to indicate async hooks
exitHook.uncaughtExceptionHandler((err, callback) => {
sendErrorToCloudOrWhatever(err) // Returns promise
.then(() => {
console.log('Sent err to cloud');
});
.catch(sendError => {
console.error('Error sending to cloud: ', err.stack));
})
.then(() => callback);
});
});
// Add exit hooks for a signal or custom message:
// Custom signal
// Arguments are `signal, exitCode` (SIGBREAK is already handled, this is an example)
exitHook.hookEvent('SIGBREAK', 21);
// process event: `message` with a filter
// filter gets all arguments passed to *handler*: `process.on(message, *handler*)`
// Exits on process event `message` with msg `customShutdownMessage` only
exitHook.hookEvent('message', 0, msg => msg !== 'customShutdownMessage');
// All async hooks will work with uncaught errors when you have specified an uncaughtExceptionHandler
throw new Error('awesome');
//=> // Sync uncaughtExcpetion hooks called and retun
//=> '[Error: awesome]'
//=> // Sync hooks called and retun
//=> 'exiting'
//=> 'exiting 2'
//=> // Async uncaughtException hooks return
//=> 'Sent error to cloud'
//=> // Sync uncaughtException hooks return
//=> 'exiting 3'
MIT © Tapani Moilanen
MIT © Sindre Sorhus
2.0.1 (2017-08-03)
<a name="2.0.0"></a>
FAQs
Run some code when the process exits (supports async hooks and pm2 clustering)
The npm package async-exit-hook receives a total of 1,282,929 weekly downloads. As such, async-exit-hook popularity was classified as popular.
We found that async-exit-hook demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.