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

iris-error-handler

v1.2.0

Published

Resource for internal Iris error codes and middleware

Readme

Iris Error Handler

Error handling middleware for IrisVR microservices.

  1. Getting Started
  2. Error Table
  3. API
  4. Testing
  5. Contribution

Compatible with Node.js + Express apps, with an optional MongoDB backend.

CircleCI Codecov

Getting started

Installation

$ npm install iris-error-handler --save

Initialization

const errorHandler = require('iris-error-handler');

Error Table

You may conjure the list of internal Iris error codes and their respective messages like this:

const errorTable = require('iris-error-handler').errorTable;

The error code acts as the key, while the value contains the meta payload to be returned to the client. The meta object contains the following fields:

  • code: An integer value that categorizes the type of response according to our internal status code library. This number is unrelated to a standard HTTP status code.
  • error_type: A brief description of the error.
  • error_message: A string that describes error in full detail.

Organization

  • -1: Unknown error. This is the default error returned by the middleware if no error code is specified.
  • 1 - 99: Third-party errors
  • 100 - 149: Request header errors
  • 150 - 199: MongoDB errors
  • 200 - 299: User / Password errors
  • 300 - 399: Library errors
  • 400 - 499: Team errors
  • 500 - 599: Billing errors
  • 600 - 699: Notification errors

Example

{
  ...
  202: {
    meta: {
      code: 202,
      error_type: 'UsernameTaken',
      error_message: 'The username is already registered'
    }
  },
  ...
}

API

const errorUtils = require('iris-error-handler').utils;

General

handleError(res)(err)

Currying function that accepts an Express response object and an error argument. This method internally triggers sendError for ultimately sending the response back to the client.

The error passed in must be one of two types:

Example
/**
 * route.js
 */
// Arbitrary error thrower
function calculate() {
  return Promise.reject(Error(101));
};

// Route handler
const calculateNumber = (req, res) => 
  calculate(req.body)
    .then(n => res.send(n))
    .catch(errorUtils.handleError(res));
  • A Mongoose Error triggered by validators defined in the schema. There are two types of mongoose errors that we support:
Required Field Error

The required field validator comes out of the box when you define your schema. The actual error code you want to throw for specific missing fields can be configured here.

Example
/**
 * userModel.js
 */
const User = new mongoose.Schema({
  username: {
    type: String
  },
  password: {
    type: String,
    required: true // built-in validator
  }
});

module.exports = mongoose.model('User', User);

/**
 * route.js
 */
const User = mongoose.model('User');
const createUser = (req, res) => {
  const userWithoutPassword = { username: '[email protected]' };
  User.create(userWithoutPassword)
    .then(u => res.send(u))
    .catch(errorUtils.handleError(res)); // Sends `205: PasswordMissing`
}
Custom Validation Error

You can set up custom validation on your schema using .validate(callback, [message]). If you do so, make sure to pass in the appropriate error code as the second argument.

Custom Validation Example
/**
 * userModel.js
 */
const User = new mongoose.Schema({
  username: String
});

// Custom validator. Note that the second argument is an Iris error code.
User.path('username').validate(callback, '201');

function callback(value, respond) {
  return validator.isEmail(value)
    ? respond(true) : respond(false);
}

module.exports = mongoose.model('User', User);

/**
 * route.js
 */
const User = mongoose.model('User');
const createUser = (req, res) =>
  User.create({ username: 'INVALID_EMAIL_FORMAT' })
    .then(u => res.send(u))
    .catch(errorUtils.handleError(res)); // Sends `201: UsernameInvalid`

sendError(res, code)

Accepts an Express response object and an Iris error code. The code is referenced against the error table and the appropriate response payload is sent to the client. If no code is passed, the method will default to -1: UnknownError.

The client should always expect a successful HTTP 200 status for errored responses, as more detailed information about the error will be provided in the response body. Refer to the error table for a breakdown of the payload.

This method should not be called directly as it is invoked by the wrapper method handleError. However, it may be convenient to use in development.

Example
const responder = (req, res) =>
  errorUtils.sendError(res, 101);

MongoDB

validateObjectID(id)

Confirms whether a string is a valid Mongo ObjectID; if so, the string is passed on to the next middleware.

This method should be placed directly before making database queries that involve document ID(s).

Example
const User = mongoose.model('User');
const getUser = (req, res) => {
  const id = req.user._id;
  errorUtils.validateObjectID(id)
    .then((id) => User.findById(id))
    .then(u => res.send(u))
    .catch(errorUtils.handleError(res));  // Sends `150: ObjectIDInvalid`
}

handleEntityNotFound(entity, [category])

Checks whether the relevant document exists in the database; if so, the document is passed on to the next middleware.

This method should be placed directly after a database query.

An optional category argument can specify what type of document was(n't) found. If none is provided, the error will default to 160: NotFound. A dictionary of supported category strings are available here.

Example
const User = mongoose.model('User');
const getUser = (req, res) =>
  User.findById(req.user._id)
    .then(u => errorUtils.handleEntityNotFound(u, 'userId'))
    .then(u => res.send(u))
    .catch(errorUtils.handleError(res)); // Sends `204: UserIDNotFound`

validateOwner(user)(document)

Confirms whether a user has access to a document; if so, the document is passed on to the next middleware.

This is a lesser used method that only applies to documents with an owner.username field, such as Panos in the Library service.

Example
const Document = mongoose.model('Document');
const updateDocument = (req, res) => {
  const user = req.user;
  const documentId = req.body._id;

  Document.findbyId(documentId)
    .then(errorUtils.validateOwner(user))
    .then(d => res.send(d))
    .catch(errorUtils.handleError(res)); // Sends `350: PermissionsError`
}

Testing

Unit and integration tests are contained in /specs. Make sure to install all dev dependencies required for the testing environment.

$ git clone https://github.com/IrisVR/iris-error-handler.git
$ cd iris-error-handler
$ npm install

Even though this module itself does not require Express or Mongo, it provides support for services using that tech stack. As a result, a server and DB must be mocked in testing.

Linting

$ npm run lint

Running tests

Run unit tests once

$ npm test

Run tests on file change

$ npm run test:watch

Code coverage

$ npm run coverage

All of the above

$ npm run validate

This script uses npm-run-all --parallel under the hood to execute the processes simultaneously.

Contribution

If you'd like to contribute, please make a pull request to the develop branch for imminent review.

Making Changes

Error Codes

Prior to adding a new error code, ensure that a synonymous one doesn't already exist in the error table. If it's indeed a new one, either find a relevant category for it (e.g. User errors fall under 200-299) or create a new category and assign a new group of 100 integers.

If applicable, you may want to update the requiredField and/or notFound dictionary.

Methods

New methods should be placed in /utils; those specific to individual microservices should be placed in /utils/services. All new and/or updated methods should have corresponding unit and integration tests.

Committing and Releasing

To release updates, you must be part of the IrisVR NPM Organization.

Preview

To preview the contents of the npm module prior to publishing:

$ npm pack

This will create the tar zip file that would be served by npm. You can unzip it and explore its contents, which should consist of the following:

dist/
LICENSE
README.md
package.json

When the module is require'd, package.json will point the user to the relevant entry point at dist/index.js.

Commit

The module uses commitizen for making commits, which is included in the dev dependencies.

$ git add -A
$ npm run commit

This will prompt a CLI to walk you through the changes you made. Only a commit type of feat or fix will trigger an update to the published npm module; other types such as refactor and style will not be a release as they don't change anything from the user's perspective.

Committing will run a githook that triggers npm run validate, which in turn runs npm test, npm run lint and npm run coverage in parallel. If there is an error at any stage, the commit will be rejected.

Publish

Once a PR is merged into develop, CircleCI will ensure that the codebase is properly tested, linted and covered.

In the case where develop is merged into master, CirclCI will additionally create a release build, make a new tag according to the nature of the update (major, minor or patch), and auto-release the new version to npm.