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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@aqo/exception

v1.0.2

Published

error extension for graceful exception handling

Downloads

12

Readme

exception

Error extension for graceful exception handling.

Usage

function Exception(messageOrError, assign = {})

messageOrError: can be String or Error or Exception

assign: optional, if provided must be Object

  • if messageOrError is String, sets the message, and stack is set from point code was called
  • if messageOrError is Error or Exception, sets the message and stack from that Error/Exception
  • if assign is provided, all of its keys are assigned to the Exception being created

bonus "hidden" global configuration options that affect all Exceptions:

Exception.toRemoveNodeInternals = true;

If you set this to true, all Exceptions will remove Node.js internals from stack traces. This makes stacks a lot more compact and easier to read, at the price of potentially missing an actual error in Node.js's implementation if one happens.

Exception.trimPath = require('path').resolve(__dirname, '..');

If you set trimPath to a non-empty string, this path will be stripped from all paths in both the trace and the error message, making it more compact and easier to read, at the price of potentially missing relevant information.

Examples

const Exception = require('@aqo/exception');

// throw an error (this is native JavaScript, no external modules)
try {
	throw Error('message');
} catch(error) {
	console.log(
		'\nerror instanceof Error:', error instanceof Error, // true
		'\nerror instanceof Exception:', error instanceof Exception, // false
	);
}

// throw an exception (this is using this package)
try {
	throw Exception('message');
} catch(error) {
	console.log(
		'\nerror instanceof Error:', error instanceof Error, // true
		'\nerror instanceof Exception:', error instanceof Exception, // true
	);
}

// throw an exception with extra properties
try {
	throw Exception('human friendly message as long as needed for debugging', { // message is unreliable for testing, i.e. can be dynamically generated, etc
		code: 'ERR_MACHINE_FRIENDLY_VALUE', // reliable for testing, should be final once decided on
		data: 'blob of information that can be useful for debugging', // actual data depends on code
	});
} catch(error) {
	switch(error.code) {
		case 'ERR_MACHINE_FRIENDLY_VALUE':
			console.error('known exception type happened:', error.message, error.data);
			break;
		default:
			console.error('unknown error happened:', error);
	}
}

// convert errors into exceptions
try {
	JSON.parse('not-json-data');
} catch(error) {
	console.error(Exception(error, { // keeps error's original message, stack, and other keys
		code: 'ERR_JSON_PARSE', // if error already had a .code key, this overwrites it
	}));
}

// also works with existing exceptions
console.log(Exception(Exception('multi-level error handling', {
	foo: 'inner level',
	bar: 'inner level',
}), {
	foo: 'outer level',
})); // should have foo: 'outer level', bar: 'inner level'

// you can also use `new` to create Exceptions, but it's recommended to avoid it
const myException = new Exception('foo');
// same result as const myException = Exception('foo');

Why

Errors and exceptions are not the same thing.

Errors are something unexpected, that you should fix whenever you encounter. It makes sense for those to be thrown by your environment.

Exceptions are something you expect, that you can capture and handle. It makes sense for those to be thrown by users.

In JavaScript, there is only an Error object, which only lets you put a message, and generates a stack trace. This is enough to debug an actual error, but not enough to have exceptions that you handle in runtime.

Very often a piece of code can have one happy path and then multiple failure points, and you want to give the caller a graceful way to handle different failure points separately. Exactly how to do it is opinionated.

This Exception constructor gives you an unopinionated way to extend an Error with any keys you wish, while keeping the original stack trace, and being compatible with instanceof tests. Each project can choose its own style of Error extension.

The recommended style this package was created for is to add a "code" key with a string value in the format of "ERR_SHORT_ERROR_DESCRIPTION", and any arbitrary other keys that depend on the code. This allows you to provide callers with an easy way to choose which error types they want to handle (test .code's value) while being transparent about the error type and not using any ambiguous magic values that require checking docs to use. The "ERR_" prefix is also search-friendly allowing you to quickly find all error codes in a large chunk of code.

However you may use this any way that you see fit.

License

ISC