npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

unhandled-rejection

v1.0.0

Published

Catch unhandled rejections, no matter what Promises implementation they come from

Downloads

1,922

Readme

unhandled-rejection

Unfortunately, there's quite a bit of variation between different Promises implementations and environments, in how you are supposed to (globally) detect unhandled rejections. This can make it tricky to reliably log such errors, especially in browsers.

This module provides a single unified API for detecting unhandled rejections (and their subsequent handling, if any). It works in Browserified/Webpacked environments as well, as long as the Promises implementations support it.

Don't ignore unhandled errors. This module is meant to be used for implementing log-and-crash logic - once an unexpected error (ie. bug) occurs, it is not safe to continue, as your application is now in an unpredictable state. You should instead let your application crash after logging the error, to start over with a 'clean slate'.

Supported implementations

If your favourite Promises implementation or environment is not (correctly) supported by this module yet, please open a ticket!

| | Node.js | WebWorkers | Modern browsers | Old browsers | |-------------------------|---------|------------|-----------------|--------------| | Bluebird (> 2.7.0) | ✓ | ✓ | ✓ | ✓ | | ES6 Promises (Node.js)¹ | ✓ | n/a | n/a | n/a | | ES6 Promises (WHATWG)² | n/a | ✓ | ✓ | n/a | | Q | ✓ | ✗ | ✗ | ✗ | | WhenJS | ✓ | ✓⁴ | ✓⁴ | ✗ | | Yaku | ✓ | ✓ | ✓ | ✓ | | es6-promise | ✗ | ✗ | ✗ | ✗ | | then/promise | ✗ | ✗ | ✗ | ✗ | | (other, per spec)³ | ✓ | n/a | n/a | n/a |

| Symbol | Meaning | |--------|----------------------------------------------| | ✓ | Implemented and supported. | | ✗ | Not implemented - library does not support global rejection events in this environment. | | n/a | Specification does not cover this environment. | | ¹ | Node.js implementation | | ² | WHATWG specification | | ³ | @benjamingr's specification | | ⁴ | Implementation exists, but is currently completely broken in bundled environments, such as Webpack and Browserify. (issue) |

License

WTFPL or CC0, whichever you prefer. A donation and/or attribution are appreciated, but not required.

Donate

Maintaining open-source projects takes a lot of time, and the more donations I receive, the more time I can dedicate to open-source. If this module is useful to you, consider making a donation!

You can donate using Bitcoin, PayPal, Flattr, cash-in-mail, SEPA transfers, and pretty much anything else. Thank you!

Contributing

Pull requests welcome. Please make sure your modifications are in line with the overall code style, and ensure that you're editing the files in src/, not those in lib/.

Build tool of choice is gulp; simply run gulp while developing, and it will watch for changes.

Be aware that by making a pull request, you agree to release your modifications under the licenses stated above.

Make sure to read the implementation-details.md beforehand. The various unhandledRejection APIs are extremely finicky, and it's tricky to work out exactly how you can make everything play together nicely. When making a pull request, make sure to intensively check that you haven't broken anything in the process.

Usage

const unhandledRejection = require("unhandled-rejection");

// Assuming `loggingServer` is some kind of logging API...

let rejectionEmitter = unhandledRejection({
	timeout: 20
});

rejectionEmitter.on("unhandledRejection", (error, promise) => {
	loggingServer.registerError(error);
});

rejectionEmitter.on("rejectionHandled", (error, promise) => {
	loggingServer.registerHandled(error);
})

Rejections and timeouts

Due to the asynchronous nature of Promises, it's never completely certain that a rejection is unhandled - for example, a handler may be attached at a later point. For this reason, many Promise implementations provide a rejectionHandled event that essentially 'rectifies' an earlier unhandledRejection event, indicating that it was handled after all.

Because not all of these APIs are consistent, this module has to internally keep track of unhandled promises that it has encountered. The problem is that this means it has to keep a reference to every Error that it encounters, which in turn will get in the way of the garbage collector - eventually creating a memory leak.

To prevent this, you can configure a timeout setting (defaulting to 60 seconds), after which the module will consider a rejection to have been 'final', so that it can remove it from its internal list, thereby freeing up memory. If a rejectionHandled for the error comes in after this timeout, it will be silently ignored.

Situations where it takes more than 60 seconds to attach a .catch handler are rare, but if you run into such a situation, you can increase the timeout value to accommodate that.

API

unhandledRejection(options)

Returns a new emitter.

  • options:
    • timeout: Defaults to 60. The amount of time after which an unhandled rejection should be considered 'final'. See the "Timeout" section above for more information.

emitter.on("unhandledRejection", callback)

Emitted whenever an unhandled rejection is encountered. The callback arguments are as follows:

  • error: The Error object (or other error value) that the rejection occurred with.
  • promise: The Promise for which the error occurred.

emitter.on("rejectionHandled", callback)

Emitted when a previously 'unhandled' rejection was handled after all (within the timeout). The callback arguments are as follows:

  • error: The Error object (or other error value) that the original rejection occurred with.
  • promise: The Promise for which the error originally occurred.