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

@fwoom/error

v1.0.0

Published

A small error utility for creating consistent, safe, and portable application errors.

Readme

@fwoom/error

A small, framework-agnostic error utility for JavaScript and TypeScript applications.

@fwoom/error is designed to be simple, safe by default, and portable. It helps you create consistent, structured errors without forcing class-based inheritance or framework-specific concepts.


Installation

npm install @fwoom/error

Core Concepts

Errors are data

Errors are identified by a stable error code, not by instanceof checks or class inheritance.

This makes errors:

  • Portable across runtimes
  • Serializable
  • Safe to handle in distributed systems

Public API

@fwoom/error intentionally exposes only two main APIs:

  • defineError() – define an error type and get a reusable factory
  • createError() – create an error by code (zero-config fallback)

In addition, it exports a small set of standard error factories.


Defining Custom Errors

Use defineError to declare an error type and its defaults. This is usually done once and exported.

import { defineError } from "@fwoom/error";

export const userNotFound = defineError({
	code: "USER_NOT_FOUND",
	status: 404,
	expose: true,
	message: "User not found",
});

defineError:

  • Registers error metadata
  • Returns a callable error factory
  • Is safe to import anywhere (module runs once)

Using Error Factories

The returned factory is what you throw at runtime.

Message only

throw userNotFound("User not found");

Message with details

throw userNotFound("User not found", { userId: 123 });

Override options

throw userNotFound("User not found", {
	status: 410,
	expose: true,
	details: { userId: 123 },
});

createError (Zero-config usage)

createError lets you create errors by code without defining them first.

import { createError } from "@fwoom/error";

throw createError("SOMETHING_BROKE");

With a custom message:

throw createError("NOT_FOUND", "User not found");

With full options:

throw createError("CUSTOM_ERROR", {
	message: "Something went wrong",
	status: 400,
	expose: false,
	details: { reason: "invalid_state" },
});

If the error code was not defined via defineError, a development-only warning is shown.


Standard Error Factories

@fwoom/error provides common HTTP-style errors out of the box.

import {
	badRequest,
	unauthorized,
	forbidden,
	notFound,
	conflict,
	unprocessableEntity,
	internalError,
} from "@fwoom/error";

Available standard errors

| Factory | Code | Status | Exposed | Default message | | --------------------- | ---------------------- | ------ | ------- | -------------------- | | badRequest | BAD_REQUEST | 400 | true | Bad request | | unauthorized | UNAUTHORIZED | 401 | true | Unauthorized | | forbidden | FORBIDDEN | 403 | true | Forbidden | | notFound | NOT_FOUND | 404 | true | Not found | | conflict | CONFLICT | 409 | true | Conflict | | unprocessableEntity | UNPROCESSABLE_ENTITY | 422 | true | Unprocessable entity | | internalError | INTERNAL_ERROR | 500 | false | Internal error |

Example:

throw notFound("User not found", { userId: 123 });

Error Fields

All errors produced by this package share the same shape:

interface BaseError extends Error {
	code: string;
	message: string;
	status?: number;
	expose: boolean;
	details?: unknown;
	cause?: unknown;
}

Defaults and Safety

  • status defaults to 500
  • expose defaults to false
  • message falls back to the error code

This ensures that errors are safe by default, even in zero-config usage.


Development vs Production Behavior

Development

  • Warns when createError is used with an undefined error code
  • Warns on duplicate defineError calls
  • Never throws because of misconfiguration

Production

  • No warnings
  • Same runtime behavior
  • Safe messages only

Why no classes or instanceof

@fwoom/error intentionally avoids class-based errors.

Instead of:

if (err instanceof ValidationError) {
}

Use:

if (err.code === "VALIDATION_FAILED") {
}

This approach is:

  • More portable
  • Stable across package boundaries
  • Safer in distributed systems

Philosophy

Errors should be:

  • Explicit, not implicit
  • Data-first, not inheritance-based
  • Safe by default
  • Easy to create, hard to misuse

License

MIT