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 🙏

© 2025 – Pkg Stats / Ryan Hefner

non-error

v0.1.0

Published

An error subclass for wrapping non-error values

Downloads

6,075

Readme

non-error

An error subclass for wrapping non-error values

Wrap non-error values in a proper Error subclass. JavaScript allows throwing any value, but only Error instances have stack traces and proper debugging context. This package converts non-error values (strings, numbers, objects, etc.) into proper errors while preserving the original value.

Install

npm install non-error

Usage

import NonError from 'non-error';

const error = new NonError('Something went wrong');

console.log(error.message);
//=> 'Non-error value: Something went wrong'

console.log(error.value);
//=> 'Something went wrong'

console.log(error.isNonError);
//=> true

// Works with any value type
new NonError(404);
new NonError({code: 'ERR_NOT_FOUND'});
new NonError(undefined);

API

new NonError(value, options?)

Wraps a non-error value into an Error object.

This class is meant to be used when a value that is not an Error needs to be thrown or used as an error. JavaScript allows throwing any value, but this is considered bad practice. This class helps enforce proper error handling by converting any thrown value into a proper Error instance.

value

Type: unknown

The value to wrap.

The error message will be a string representation of this value, and the original value will be stored in the value property.

If value is already a NonError instance, it is returned as-is. If value is an Error instance, a TypeError is thrown (throw the Error directly instead).

options

superclass

Type: ErrorConstructor
Default: Error

The superclass to extend from instead of Error.

This can be useful if you need NonError to extend a custom error class.

import NonError from 'non-error';

const error = new NonError('test', {superclass: TypeError});

console.log(error instanceof TypeError);
//=> true

console.log(error instanceof NonError);
//=> true

error.isNonError

Type: true (read-only)

Identify NonError instances. Always true.

error.value

Type: unknown (read-only)

The original unwrapped value.

import NonError from 'non-error';

const error = new NonError(404);
console.log(error.value);
//=> 404

NonError.isNonError(value)

Returns: boolean

Check if a value is a NonError instance.

import NonError from 'non-error';

const error = new NonError('test');
console.log(NonError.isNonError(error));
//=> true

console.log(NonError.isNonError(new Error('test')));
//=> false

NonError.try(callback)

Executes the callback immediately and wraps any non-error throws in NonError. Real Error instances are re-thrown unchanged.

Supports both sync and async functions.

import NonError from 'non-error';

// Non-error throws get wrapped
try {
	NonError.try(() => {
		throw 'string error';
	});
} catch (error) {
	console.log(error.isNonError);
	//=> true
}

// Real errors pass through unchanged
try {
	NonError.try(() => {
		throw new TypeError('type error');
	});
} catch (error) {
	console.log(error instanceof TypeError);
	//=> true
}

NonError.wrap(function)

Returns a wrapped function that catches non-error throws and wraps them in NonError. Real Error instances are re-thrown unchanged.

Supports both sync and async functions.

Useful for array methods, promise chains, and callbacks that are invoked synchronously or by code with error handling.

import NonError from 'non-error';

// Array operations
const results = items.map(NonError.wrap(transform));

Best practices

  • Always throw Error instances, never strings, numbers, or plain objects.
  • Use NonError to convert non-error values when needed.
  • Keep error cause chains proper (wrap non-error causes with NonError).
  • Better TypeScript ergonomics: by ensuring all thrown values are Error instances, error handling code can work with Error type instead of unknown.

FAQ

Why doesn't this accept the value in a cause option?

You might wonder why you can't do new NonError('message', {cause: nonErrorValue}).

While JavaScript's spec allows any value in the cause property, I think this is a design mistake. The cause property should always be an Error instance (or undefined) because:

  • Non-error causes lack stack traces, losing critical debugging context about where the root cause originated
  • It breaks TypeScript ergonomics, forcing error.cause to be typed as unknown instead of Error | undefined
  • Every code path has to safe-guard against non-errors

How is this different from ensure-error?

ensure-error fixes everything: wraps non-errors AND normalizes broken Error instances (adds missing stack, recursively fixes .cause and AggregateError#errors chains). Use it in catch blocks when you want all errors normalized and cleaned up.

non-error only wraps non-errors. Real Error instances pass through unchanged. It's a more low-level component.

Related

  • ensure-error - Ensures a value is a valid error by making it one if not