promise-leak
v2.0.0
Published
Dev-mode runtime detection of unhandled/floating promises in Node.js
Maintainers
Readme
promise-leak
Runtime detection of unhandled/floating promises in Node.js — not just rejections, but promises that are created and never awaited or .catch()-ed (the "fire and forget" pattern that silently swallows errors).
Written in TypeScript. Built output is in dist/ (CommonJS + .d.ts).
Install
npm install promise-leak --save-devQuick start
At the very top of your entry file (before any other requires):
require('promise-leak/register');
// or
import 'promise-leak/register';Or run your app with Node’s -r flag:
node -r promise-leak/register server.jsProgrammatic API
import {
PromiseLeak,
intentional,
forget,
track,
createTestDetector,
runWithLeakCheck,
} from 'promise-leak';
const detector = new PromiseLeak({
ttl: 100,
stackDepth: 10,
ignore: [/node_modules/], // string | RegExp | (leak: LeakEntry) => boolean
onLeak: (leak) => { /* custom handler */ },
mode: 'warn', // 'warn' | 'throw' | 'silent' | 'strict'
groupBy: 'location', // 'location' | 'stack' | 'none'
maxLeaks: Infinity,
});
detector.start();
// Intentionally fire-and-forget (suppress report):
intentional(sendAnalytics());
forget(somePromise); // same as intentional()
// Track promises from native APIs (e.g. fetch) after install():
track(fetch('/api'));
// Teardown
detector.stop();
const report = detector.getReport();
detector.reset();
// Tests: strict preset
const testDetector = createTestDetector(); // mode: 'throw', short ttl, ignore: [/node_modules/]
// CLIs / scripts: fail if there are leaks
await runWithLeakCheck(async () => {
// your script logic here
});HTTP / Express-style middleware
import express from 'express';
import { createLeakMiddleware } from 'promise-leak';
const app = express();
app.use(createLeakMiddleware({ groupBy: 'location' }));Each request is checked after it finishes; any floating promises are logged (or cause an error if mode: 'throw').
CLI
After installing globally or as a dev dependency, you can run scripts via:
npx promise-leak run path/to/script.js --arg1 --arg2promise-leak will preload the detector, run your script, and exit non‑zero if any floating promises are detected.
Jest / Vitest
import { promiseLeakAfterEach, promiseLeakStop } from 'promise-leak/jest';
afterEach(promiseLeakAfterEach({ ttl: 50 }));
afterAll(promiseLeakStop);What gets reported
A leak is a promise that, within the TTL window, was never:
- awaited
- chained with
.then()or.catch()or.finally() - passed into
Promise.all/Promise.race/Promise.allSettled/Promise.any
So “fire and forget” calls like saveToDb(data) without await or .catch() are reported with a stack trace.
Types
LeakEntry– one detected leak (id, stack, location, promiseState, etc.)PromiseLeakOptions– options fornew PromiseLeak(options)LeakMode,StackLocation– as needed
Build
npm run buildThis runs tsc and emits dist/ (JS + declaration files).
License
MIT
