A base class for JavaScript errors
JavaScript
Switch branches/tags
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
modules
.gitignore
.travis.yml
README.md
package.json

README.md

UserError Travis npm package

UserError is a base class that makes JavaScript errors a lot more useful. It gives you:

  • An Error subclass that actually works
  • Support for checking error types using instanceof
  • A correct name property on error objects
  • Cleaner stack traces

Installation

Using npm:

$ npm install --save usererror

Rationale

To see the problems UserError solves for you, let's try to subclass Error directly and see what happens.

class MyError extends Error {
  constructor(message) {
    super(message)
  }
}

const boom = () => {
  throw new MyError('boom!')
}

try {
  boom()
} catch (error) {
  error instanceof Error    // true  (correct)
  error instanceof MyError  // false (wrong, should be true)
  error.name                // Error (wrong, should be MyError)
}

In this example, subclassing Error is useless; we can't really differentiate an instance of MyError from any other Error in the system. This inability to subclass Error has led to a number of other workarounds, most often adding some kind of code property to error objects, so you end up doing stuff like this:

if (error.code === SomeErrorCode)
  // ...

In addition to this problem, errors created in this way include extra noise in their stack trace:

Error: boom!                              << should be "MyError: boom!"
    at MyError.Error (native)             << noise
    at new MyError (test.js:3:7)          << noise
    at boom (test.js:10:9)
    at Object.<anonymous> (test.js:14:3)

UserError aims to fix these problems. Now, when we run the example it looks like this:

import UserError from 'usererror'

class MyError extends UserError {
  constructor(message) {
    super(message)
  }
}

const boom = () => {
  throw new MyError('boom!')
}

try {
  boom()
} catch (error) {
  error instanceof Error    // true
  error instanceof MyError  // true
  error.name                // MyError
}

Since both instanceof work and the name property is setup correctly, we can do either

if (error instanceof MyError)
  // ...

or

if (error.name === 'MyError')
  // ...

instead of duck-typing with a custom property. Additionally, the stack trace doesn't contain unnecessary entries:

MyError: boom!
    at boom (test.js:10:9)
    at Object.<anonymous> (test.js:14:3)