Socket
Socket
Sign inDemoInstall

make-promises-safe

Package Overview
Dependencies
0
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    make-promises-safe

Crash or abort if you get an unhandledRejection or multipleResolves


Version published
Weekly downloads
86K
increased by13%
Maintainers
1
Install size
10.3 kB
Created
Weekly downloads
 

Readme

Source

make-promises-safe   Build Status

A node.js module to make the use of promises safe. It implements:

  1. the deprecation DEP0018 of Node.js in versions >= 6, as using Promises without this module might cause file descriptor and memory leak; follow this for more details.
  2. exiting on multiple resolve or reject, as those could hide bugs that will be completely silent; follow this for more details.

Install

npm install make-promises-safe --save

Usage

'use strict'

require('make-promises-safe') // installs an 'unhandledRejection' handler
const http = require('http')
const server = http.createServer(handle)

server.listen(3000)

function handle (req, res) {
  doStuff()
    .then((body) => {
      res.end(body)
    })
}

function doStuff () {
  if (Math.random() < 0.5) {
    return Promise.reject(new Error('kaboom'))
  }

  return Promise.resolve('hello world')
}

as a preloader

You can add this behavior to any Node.js application by using it as a preloader:

node -r make-promises-safe server.js

with core dumps

You can also create a core dump when an unhandled rejection occurs:

require('make-promises-safe').abort = true

The 'unhandledRejection' problem

Node.js crashes if there is an uncaught exception, while it does not crash if there is an 'unhandledRejection', i.e. a Promise without a .catch() handler.

If you are using promises, you should attach a .catch() handler synchronously.

As an example, the following server will leak a file descriptor because of a missing .catch()  handler:

const http = require('http')
const server = http.createServer(handle)

server.listen(3000)

function handle (req, res) {
  doStuff()
    .then((body) => {
      res.end(body)
    })
}

function doStuff () {
  if (Math.random() < 0.5) {
    return Promise.reject(new Error('kaboom'))
  }

  return Promise.resolve('hello world')
}

The Solution

make-promises-safe installs an process.on('unhandledRejection') handler that prints the stacktrace and exits the process with an exit code of 1, just like any uncaught exception.

Promises that resolves or rejects multiple times

Promises whose resolve or reject functions are called multiple times might cause memory or file descriptor leaks, as resource might not be consumed correctly.

As an example, the following code will error with a EMFILE:

const http = require('http')
const fs = require('fs')
const stream = require('stream')
const { promisify } = require('util')
const pipeline = promisify(stream.pipeline)
const server = http.createServer(handle)

server.listen(3000)

function handle (req, res) {
  openFile()
    .then((body) => {
      return pipeline(body, res)
    })
    .catch((err) => {
      res.statusCode = 500
      res.end(err.toString())
    })
}

function openFile () {
  return new Promise(function (resolve, reject) {
    // this simulates some other parts of the codebase that
    // could throw an error
    if (Math.random() < 0.5) {
      // note that a deveveloper forgot to return
      reject(new Error('kaboom'))
    }

    // we are creating a file even if the promise errored,
    // and it is never consumed or closed
    resolve(fs.createReadStream(__filename))
  })
}

Under load, the above script will exits with an EMFILE error that would be extremely hard to debug.

The Solution

make-promises-safe installs an process.on('multipleResolves') handler that prints the type of event, the promise and the reason (the value that resolve or reject were called with) and exits the process with an exit code of 1.

This feature is available only on Node >= 10.12.0.

License

MIT

Keywords

FAQs

Last updated on 01 Nov 2018

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.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc