Gathering detailed insights and metrics for @jsdevtools/ono
Gathering detailed insights and metrics for @jsdevtools/ono
Gathering detailed insights and metrics for @jsdevtools/ono
Gathering detailed insights and metrics for @jsdevtools/ono
Wrap errors without losing the original message, stack trace, or properties
npm install @jsdevtools/ono
99.7
Supply Chain
100
Quality
79.4
Maintenance
100
Vulnerability
100
License
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
106 Stars
397 Commits
11 Forks
4 Watching
3 Branches
5 Contributors
Updated on 18 Aug 2024
Minified
Minified + Gzipped
JavaScript (64.73%)
TypeScript (35.27%)
Cumulative downloads
Total Downloads
Last day
-6.7%
757,385
Compared to previous day
Last week
0.8%
4,252,154
Compared to previous week
Last month
10.2%
17,990,180
Compared to previous month
Last year
48.9%
172,214,958
Compared to previous year
Wrap and re-throw an error without losing the original error's type, 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
Supports and enhances your own custom error classes
Tested on Node.js and all modern web browsers on Mac, Windows, and Linux.
1const ono = require("@jsdevtools/ono"); 2 3// Throw an error with custom properties 4throw ono({ code: "NOT_FOUND", status: 404 }, `Resource not found: ${url}`); 5 6// Wrap an error without losing the original error's stack and props 7throw ono(originalError, "An error occurred while saving your changes"); 8 9// Wrap an error and add custom properties 10throw ono(originalError, { code: 404, status: "NOT_FOUND" }); 11 12// Wrap an error, add custom properties, and change the error message 13throw ono(originalError, { code: 404, status: "NOT_FOUND" }, `Resource not found: ${url}`); 14 15// Throw a specific Error subtype instead 16// (works with any of the above signatures) 17throw ono.range(...); // RangeError 18throw ono.syntax(...); // SyntaxError 19throw ono.reference(...); // ReferenceError 20 21// Create an Ono method for your own custom error class 22const { Ono } = require("@jsdevtools/ono"); 23class MyErrorClass extends Error {} 24ono.myError = new Ono(MyErrorClass); 25 26// And use it just like any other Ono method 27throw ono.myError(...); // MyErrorClass
Install using npm:
1npm install @jsdevtools/ono
When using Ono in Node.js apps, you'll probably want to use CommonJS syntax:
1const ono = require("@jsdevtools/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:
1import ono from "@jsdevtools/ono";
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.
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. If this error's type is one of the known error types, then the new error will be of the same type.
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 the format
option for more info.
The default ono()
function may return an instance of the base Error
class, or it may return a more specific sub-class, based on the type of the originalError
argument. If you want to explicitly create a specific type of error, then you can use any of the following methods:
The method signatures and arguments are exactly the same as the default ono()
function.
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.yourCustomErrorHere() | Add your own custom error classes to ono |
Ono(Error, [options])
The Ono
constructor is used to create your own custom ono
methods for custom error types, or to change the default behavior of the built-in methods.
Warning: Be sure not to confuse
ono
(lowercase) andOno
(capitalized). The latter one is a class.
Error
- The Error sub-class that this Ono method will create instances of
options
- (optional) An options object, which customizes the behavior of the Ono method
The Ono
constructor takes an optional options object as a second parameter. The object can have the following properties, all of which are optional:
Option | Type | Default | Description |
---|---|---|---|
concatMessages | boolean | true | When Ono is used to wrap an error, this setting determines whether the inner error's message is appended to the new error message. |
format | function or boolean | util.format() in Node.jsfalse in web browsers | A function that replaces placeholders like in error messages with values. If set to false , then error messages will be treated as literals and no placeholder replacement will occur. |
concatMessages
OptionWhen wrapping an error, Ono's default behavior is to append the error's message to your message, with a newline between them. For example:
1const ono = require("@jsdevtools/ono"); 2 3function createArray(length) { 4 try { 5 return new Array(length); 6 } 7 catch (error) { 8 // Wrap and re-throw the error 9 throw ono(error, "Sorry, I was unable to create the array."); 10 } 11} 12 13// Try to create an array with a negative length 14createArray(-5);
The above code produces the following error message:
Sorry, I was unable to create the array.
Invalid array length;
If you'd rather not include the original message, then you can set the concatMessages
option to false
. For example:
1const { ono, Ono } = require("@jsdevtools/ono"); 2 3// Override the default behavior for the RangeError 4ono.range = new Ono(RangeError, { concatMessages: false }); 5 6function createArray(length) { 7 try { 8 return new Array(length); 9 } 10 catch (error) { 11 // Wrap and re-throw the error 12 throw ono(error, "Sorry, I was unable to create the array."); 13 } 14} 15 16// Try to create an array with a negative length 17createArray(-5);
Now the error only includes your message, not the original error message.
Sorry, I was unable to create the array.
format
optionThe format
option let you set a format function, which replaces placeholders in error messages with values.
When running in Node.js, Ono uses the util.format()
function by default, which lets you use placeholders such as %s, %d, and %j. You can provide the values for these placeholders when calling any Ono method:
1throw ono("%s is invalid. Must be at least %d characters.", username, minLength);
Of course, the above example could be accomplished using ES6 template literals instead of format strings:
1throw ono(`${username} is invalid. Must be at least ${minLength} characters.`);
Format strings are most useful when you don't alrady know the values at the time that you're writing the string. A common scenario is localization. Here's a simplistic example:
1const errorMessages { 2 invalidLength: { 3 en: "%s is invalid. Must be at least %d characters.", 4 es: "%s no es válido. Debe tener al menos %d caracteres.", 5 zh: "%s 无效。 必须至少%d个字符。", 6 } 7} 8 9let lang = getCurrentUsersLanguage(); 10 11throw ono(errorMessages.invalidLength[lang], username, minLength);
format
option in web browsersWeb 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 format
option to any compatible polyfill library to enable this functionality in web browsers too.
Here are some compatible polyfill libraries:
format
implementationIf the standard util.format()
functionality isn't sufficient for your needs, then you can set the format
option to your own custom implementation. Here's a simplistic example:
1const { ono, Ono } = require("@jsdevtools/ono"); 2 3// This is a simple formatter that replaces $0, $1, $2, ... with the corresponding argument 4let options = { 5 format(message, ...args) { 6 for (let [index, arg] of args.entries()) { 7 message = message.replace("$" + index, arg); 8 } 9 return message; 10 } 11}; 12 13// Use your custom formatter for all of the built-in error types 14ono.error = new Ono(Error, options); 15ono.eval = new Ono(EvalError, options); 16ono.range = new Ono(RangeError, options); 17ono.reference = new Ono(ReferenceError, options); 18ono.syntax = new Ono(SyntaxError, options); 19ono.type = new Ono(TypeError, options); 20ono.uri = new Ono(URIError, options); 21 22// Now all Ono functions support your custom formatter 23throw ono("$0 is invalid. Must be at least $1 characters.", username, minLength);
There are two ways to use Ono with your own custom error classes. Which one you choose depends on what parameters your custom error class accepts, and whether you'd prefer to use ono.myError()
syntax or new MyError()
syntax.
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
.
All of these built-in JavaScript Error types accept a single parameter: the error message string. If your own error classes also work this way, then you can create Ono methods for your custom error classes. Here's an example:
1const { ono, Ono } = require("@jsdevtools/ono"); 2let counter = 0; 3 4// A custom Error class that assigns a unique ID and timestamp to each error 5class MyErrorClass extends Error { 6 constructor(message) { 7 super(message); 8 this.id = ++counter; 9 this.timestamp = new Date(); 10 } 11} 12 13// Create a new Ono method for your custom Error class 14ono.myError = new Ono(MyErrorClass); 15 16// You can use this method just like any other Ono method 17throw ono.myError({ code: 404, status: "NOT_FOUND" }, `Resource not found: ${url}`);
The code above throws an instance of MyErrorClass
that looks like this:
1{ 2 "name": "MyErrorClass", 3 "message": "Resource not found: xyz.html", 4 "id": 1, 5 "timestamp": "2019-01-01T12:30:00.456Z", 6 "code": 404, 7 "status": "NOT_FOUND", 8 "stack": "MyErrorClass: Resource not found: xyz.html\n at someFunction (index.js:24:5)", 9}
If your custom error classes require more than just an error message string parameter, then you'll need to use Ono differently. Rather than creating a custom Ono method and using ono.myError()
syntax, you'll use Ono inside your error class's constructor. This has a few benefits:
new MyError()
syntax rather than ono.myError()
syntax1const { ono, Ono } = require("@jsdevtools/ono"); 2 3// A custom Error class for 404 Not Found 4class NotFoundError extends Error { 5 constructor(method, url) { 6 super(`404: ${method} ${url} was not found`); 7 8 // Add custom properties, enhance JSON.stringify() support, etc. 9 Ono.extend(this, { statusCode: 404, method, url }); 10 } 11} 12 13// A custom Error class for 500 Server Error 14class ServerError extends Error { 15 constructor(originalError, method, url) { 16 super(`500: A server error occurred while responding to ${method} ${url}`); 17 18 // Append the stack trace and custom properties of the original error, 19 // and add new custom properties, enhance JSON.stringify() support, etc. 20 Ono.extend(this, originalError, { statusCode: 500, method, url }); 21 } 22}
Contributions, enhancements, and bug-fixes are welcome! Open an issue on GitHub and submit a pull request.
To build/test the project locally on your computer:
Clone this repo
git clone https://github.com/JS-DevTools/ono.git
Install dependencies
npm install
Run the build script
npm run build
Run the tests
npm test
Ono is 100% free and open-source, under the MIT license. Use it however you want.
This package is Treeware. If you use it in production, then we ask that you buy the world a tree to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.
Thanks to these awesome companies for their support of Open Source developers ❤
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
dependency not pinned by hash detected -- score normalized to 3
Details
Reason
Found 0/30 approved changesets -- score normalized to 0
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no SAST tool detected
Details
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
74 existing vulnerabilities detected
Details
Score
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn Moreono
Throw better errors.
@jsdevtools/coverage-istanbul-loader
A Webpack loader that uses Istanbul to add code coverage instrumentation
@jsdevtools/ez-spawn
Simple, consistent sync or async process spawning
readdir-enhanced
fs.readdir with sync, async, streaming, and async iterator APIs + filtering, recursion, absolute paths, etc.