Skip to content
Wrap errors without losing the original message, stack trace, or properties
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src
test Removed the logic to fallback to DOMException if DOMError is unsuppor… Feb 24, 2019
.editorconfig
.eslintrc.yml
.gitattributes Updated git config files Feb 15, 2019
.gitignore
.mocharc.yml Replaced mocha.opts with .mocharc.yml Feb 24, 2019
.travis.yml
404.md setup github pages Oct 11, 2018
CHANGELOG.md
LICENSE
README.md Fixed typos in ReadMe Feb 25, 2019
_config.yml setup github pages Oct 11, 2018
karma.conf.js Moved the Babel polyfills to a test fixture so they can be loaded sep… Feb 24, 2019
package-lock.json Updated dependencies Feb 24, 2019
package.json
tsconfig.json initial typescript conversion Jan 29, 2019
tslint.yaml

README.md

ono (Oh No!)

Throw better errors.

Build Status Coverage Status

npm Dependencies License

OS and Browser Compatibility

Features

  • Wrap and re-throw an error without losing the original error's message, stack trace, and properties

  • Add custom properties to errors — great for error numbers, status codes, etc.

  • Use format strings for error messages — great for localization

  • Enhanced support for JSON.stringify() and util.inspect() — great for logging

  • Create Ono instances for your own custom error classes

  • Tested on Node.js and all modern web browsers on Mac, Windows, and Linux.

Example

const ono = require("ono");

// Throw an error with custom properties
throw ono({ code: "NOT_FOUND", status: 404 }, `Resource not found: ${url}`);

// Wrap an error without losing the original error's stack and props
throw ono(originalError, "An error occurred while saving your changes");

// Wrap an error and add custom properties
throw ono(originalError, { code: 404, status: "NOT_FOUND" });

// Wrap an error, add custom properties, and change the error message
throw ono(originalError, { code: 404, status: "NOT_FOUND" }, `Resource not found: ${url}`);

// Throw a specific Error subtype instead
// (works with any of the above signatures)
throw ono.range(...);                           // RangeError
throw ono.syntax(...);                          // SyntaxError
throw ono.reference(...);                       // ReferenceError

// Create an Ono instance for your own custom error class
const { Ono } = require("ono");
class MyErrorClass extends Error {}
ono.myError = new Ono(MyErrorClass);

// And use it just like any other Ono method
throw ono.myError(...);                         // MyErrorClass

Installation

Node

Install using npm:

npm install ono

Usage

When using Ono in Node.js apps, you'll probably want to use CommonJS syntax:

const ono = require("ono");

When using a transpiler such as Babel or TypeScript, or a bundler such as Webpack or Rollup, you can use ECMAScript modules syntax instead:

import ono from "ono";

Browser support

Ono supports recent versions of every major web browser. Older browsers may require Babel and/or polyfills.

To use Ono in a browser, you'll need to use a bundling tool such as Webpack, Rollup, Parcel, or Browserify. Some bundlers may require a bit of configuration, such as setting browser: true in rollup-plugin-resolve.

API

ono([originalError], [props], [message, ...])

Creates an Error object with the given properties.

  • originalError - (optional) The original error that occurred, if any. This error's message, stack trace, and properties will be copied to the new error.

  • props - (optional) An object whose properties will be copied to the new error. Properties can be anything, including objects and functions.

  • message - (optional) The error message string. If it contains placeholders, then pass each placeholder's value as an additional parameter. See ono.formatter for more info.

Specific error types

The default ono() function always creates Error objects, but you can use any of the following methods to explicitly create the corresponding Error subclass. The method signatures are exactly the same as above.

Method Return Type
ono.error() Error
ono.eval() EvalError
ono.range() RangeError
ono.reference() ReferenceError
ono.syntax() SyntaxError
ono.type() TypeError
ono.uri() URIError

ono.formatter

When running in Node.js, the ono.formatter property is set to the util.format() function, which let you use placeholders such as %s, %d, and %j. You can provide the values for these when calling ono or any Ono method:

throw ono("%s is invalid. Must be at least %d characters.", username, minLength);

This is especially useful for localization. Here's a simplistic example:

const errorMessages {
  invalidLength: {
    en: "%s is invalid. Must be at least %d characters.",
    es: "%s no es válido. Debe tener al menos %d caracteres.",
    zh: "%s 无效。 必须至少%d个字符。",
  }
}

let lang = getCurrentUsersLanguage();

throw ono(errorMessages.invalidLength[lang], username, minLength);

ono.formatter in web browsers

Web browsers don't have a built-in equivalent of Node's util.format() function, so format strings are only supported in Node.js by default. However, you can set the ono.formatter property to any compatible polyfill library to enable this functionality in web browsers too.

Here are some compatible polyfill libraries:

Custom ono.formatter implementation

If the standard util.format() functionality isn't sufficient for your needs, then you can set the ono.formatter property to your own custom implementation. Here's a simplistic example:

// This is a simple formatter that replaces $0, $1, $2, ... with the corresponding argument
function myCustomFormatter(message, ...args) {
  for (let [index, arg] of args) {
    message = message.replace("$" + index, arg);
  }
  return message;
}

// Tell Ono to use your custom formatter
ono.formatter = myCustomFormatter;

// Now all Ono functions support your custom formatter
throw ono("$0 is invalid. Must be at least $1 characters.", username, minLength);

Custom Error Classes

Ono has built-in support for all of the built-in JavaScript Error types. For example, you can use ono.reference() to create a ReferenceError, or ono.syntax() to create a SyntaxError. In addition to the built-in types, you can also create Ono instances for your own custom error classes.

const { ono, Ono } = require("ono");
let counter = 0;

// A custom Error class that assigns a unique ID and timestamp to each error
class MyErrorClass extends Error {
  constructor(message) {
    super(message);
    this.id = ++counter;
    this.timestamp = new Date();
  }
}

// Create a new Ono method for your custom Error class
ono.myError = new Ono(MyErrorClass);

// You can use this method just like any other Ono method
throw ono.myError({ code: 404, status: "NOT_FOUND" }, `Resource not found: ${url}`);

The code above throws an instance of MyErrorClass that looks like this:

{
  "name": "MyErrorClass",
  "message": "Resource not found: xyz.html",
  "id": 1,
  "timestamp": "2019-01-01T12:30:00.456Z",
  "code": 404,
  "status": "NOT_FOUND",
  "stack": "MyErrorClass: Resource not found: xyz.html\n   at someFunction (index.js:24:5)",
}

Contributing

Contributions, enhancements, and bug-fixes are welcome! File an issue on GitHub and submit a pull request.

Building/Testing

To build/test the project locally on your computer:

  1. Clone this repo
    git clone https://github.com/JS-DevTools/ono.git

  2. Install dependencies
    npm install

  3. Run the build script
    npm run build

  4. Run the tests
    npm test

License

Ono is 100% free and open-source, under the MIT license. Use it however you want.

Big Thanks To

Thanks to these awesome companies for their support of Open Source developers ❤

Travis CI SauceLabs Coveralls

You can’t perform that action at this time.