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 🙏

© 2026 – Pkg Stats / Ryan Hefner

rejections

v1.1.0

Published

Promise rejections helpers

Readme

Rejections

Installation

npm install --save rejections

Motivation

I do love Promises and use them everywhere. I promise. =) It is recommended practice to use instances of Error as a rejection reason of Promises. Some libs (e.g. bluebird) will even show you a warning in case you reject Promise with non-error. Straightforward solution is to use subclasses of Errors. But it leads to some complications.

Complication 1

In case you want serialize/deserialize rejection to pass it from server to client, or to save it in Redux store, you'll have to write custom serialization/deserialization code, which I feel lazy to do every time.

Complication 2

If you want to take action based on rejection class (which is the whole point behind using Error subclasses as rejections), and you are using Babel to make your code ES5-browsers compatible, then you'll have to deal with wierd issue:

class UserNotFound extends Error {
  contstructor(username) {
    super();
    this.username = username;
  }
}

new UserNotFound('Fedor') instanceof UserNotFound // will be false

To deal with both compilcatins you'll have to introduce some kind of type filed in your Error subclasses.

Solution

So why use subclasses at all? With some inspiration from redux-actions this lib provides two main functions createRejection, handleRejections and one utility function parseRejection.

createRejection(type)

Returns rejection creator for given rejection type. Creator will return Error subclass with provided payload.

const userNotFound = createRejection('user-not-found');
const networkProblem = createRejection('network-problem');

const r1 = userNotFound('Fedor');
const r2 = networkProblem({ host: 'google.com', status: 404 });

r1 instanceof Error; // true
r2 instanceof Error; // true

JSON.stringify(r1); // {"type":"user-not-found","payload":"Fedor"}
JSON.stringify(r2); // {"type":"network-problem","payload":{"host":"google.com","status":404}}

handleRejections(rejectionsMap, defaultHandler = IdentityRejector)

Creates rejections handler for given rejection types. In case no matching handler found in rejectionsMap provided rejection will be passed to defaultHandler. In case defaultHandler is not provided function re-rejecting input will be used (i.e. r => Promise.reject(r)). The result of matching handler will be returned for convinience.

const knownIssue = createRejection('known-issue');
const otherKnownIssue = createRejection('other-known-issue');

...

API.getCriticalData()
    .then(
        parseIt, // make data usable for your app
        handleRejections({
          [knownIssue]: rej => tryToRecover(rej),
          [otherKnownIssue]: rej => tryToRecoverFromAnotherIssue(rej)
        }) // unknown problem, pass reject further
    )
    .then(useIt)
    .catch(rej => {
      // was not able to recover
    });
    
...

API.getNotCriticalData()
    .then(
        parseIt, // make data usable for your app
        handleRejections({
          [knownIssue]: rej => tryToRecover(rej),
          [otherKnownIssue]: rej => tryToRecoverFromAnotherIssue(rej)
        }, rej => replaceWithDummyData()) 
    )
    .then(useIt);
    

parseRejection(raw)

Creates rejection instance from the given raw rejection data, which should be of following shape:

{
  type: String,
  payload: Anything | undefined,
}

In case raw rejection does not match that shape, rejection with type 'unknown' will be created. raw argument will be passed as its payload:

const r1 = parseRejection({ type: 'known', payload: { field: 'value' } });
// r1.type is 'known'
// r1.payload is { field: 'value' }

const r2 = parseRejection('We have failed badly');
// r2.type is 'unknown'
// r2.payload is 'We have failed badly'

const r3 = parseRejection({ type: 'not-so-well-formatted', data: 'I will dissapear!' });
// r3.type is 'not-so-well-formatted'
// r3.payload is undefined

License

Apache-2.0