# async-exit-hook

> Run some code when the process exits (supports async hooks and pm2 clustering)

Latest version **2.0.1** (published 2017-08-03) · MIT license · 3.7M weekly downloads

## Install

```sh
npm install async-exit-hook
pnpm add async-exit-hook
yarn add async-exit-hook
bun add async-exit-hook
```

## Health

**Score 53/100 (C)** — status: abandoned.

Positive: high downloads; has types package; no vulnerabilities; high quality score.

Warnings: no esm support.

Negative: abandoned.

## Facts

| | |
|---|---|
| Version | 2.0.1 |
| Published | 2017-08-03 |
| First published | 2016-03-12 |
| Weekly downloads | 3.7M |
| License | MIT |
| TypeScript types | separate (@types/async-exit-hook) |
| Module format | CommonJS |
| Node | >=0.12.0 |
| Dependencies | 0 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 116 |
| Author | Tapani Moilanen |
| Maintainers | tapppi |
| Keywords | exit, quit, process, hook, graceful, handler, shutdown, sigterm, sigint, sighup, pm2, cluster, child, reload, async, terminate, kill, stop, event |

## Links

- npm: https://www.npmjs.com/package/async-exit-hook
- Repository: https://github.com/tapppi/async-exit-hook
- Homepage: https://github.com/tapppi/async-exit-hook#readme
- Issues: https://github.com/tapppi/async-exit-hook/issues
- npm.io page: https://npm.io/package/async-exit-hook

## Alternatives

- [evnty](https://npm.io/package/evnty.md) — 7.2K weekly downloads
- [eleventy-plugin-asciidoc](https://npm.io/package/eleventy-plugin-asciidoc.md) — 3.5K weekly downloads
- [@jswork/next-get2get](https://npm.io/package/@jswork/next-get2get.md) — 945 weekly downloads
- [@dashersw/axon](https://npm.io/package/@dashersw/axon.md) — 934 weekly downloads
- [@walkeros/server-destination-criteo](https://npm.io/package/@walkeros/server-destination-criteo.md) — 323 weekly downloads

## Recent versions

- 2.0.1 (latest) — 2017-08-03
- 2.0.0 — 2017-08-03
- 1.1.2 — 2017-03-29
- 1.1.1 — 2016-11-04
- 1.1.0 — 2016-10-13
- 1.0.2 — 2016-03-12
- 1.0.1 — 2016-03-12

## README

# async-exit-hook
[![Build Status](https://api.travis-ci.org/Tapppi/async-exit-hook.svg)](https://travis-ci.org/Tapppi/async-exit-hook)
[![Coverage Status](https://coveralls.io/repos/github/Tapppi/async-exit-hook/badge.svg?branch=master)](https://coveralls.io/github/Tapppi/async-exit-hook?branch=master)

> 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:

* process SIGINT, SIGTERM and SIGHUP, SIGBREAK signals  
* process beforeExit and exit events  
* PM2 clustering process shutdown message ([PM2 graceful reload](http://pm2.keymetrics.io/docs/usage/cluster-mode/#graceful-reload))  

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](https://npmjs.com/package/exit-hook).


## Install

```
$ npm install --save async-exit-hook
```

## Usage

### Considerations and warning
#### On `process.exit()` and asynchronous code
**If 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)

#### Windows and `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.

### Clustering and child processes
If you use custom clustering / child processes, you can gracefully shutdown your child process
by sending a shutdown message (`childProc.send('shutdown')`).

### Example
```js
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'
```


## License

MIT © Tapani Moilanen  
MIT © [Sindre Sorhus](http://sindresorhus.com)

---
_Source: https://npm.io/package/async-exit-hook · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
