custom-error-instance

Create custom JavaScript Error subclasses that pass instanceof checks, with inheritance, default properties, and pluggable factories.

Library
npm
v2.1.2
10stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
21/100Needs Attention
Development Activity0
Maintenance0
Community12
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
57/100Fair
Architecture68
Code Quality45
Innovation60
Learning Curve55

custom-error-instance lets you define distinct, named JavaScript error types that extend the built-in Error object without monkey-patching it. Each custom error is a real constructor function, so instances correctly report instanceof against both the custom type and Error, and errors can inherit from other custom errors to build a hierarchy of increasingly specific failure types.

Beyond simple subclassing, the library supports default properties merged onto each instance, configurable stack trace length, and a pluggable factory system that controls exactly how an instance is populated when constructed — letting you compose behaviors like the built-in expectReceive factory for building descriptive “expected X, received Y” messages.

What You Get

  • instanceof-safe custom error constructors that also pass instanceof Error
  • error inheritance so child errors extend parent errors and their default properties
  • default properties that merge with per-instance data passed at construction
  • configurable stack trace length plus code/message getter-setter behavior
  • a pluggable factory system, including a built-in expectReceive factory for expected/received style messages

Common Use Cases

  • Building a hierarchy of domain-specific errors (e.g., MapError -> MapError.inuse) for a library or API
  • Standardizing error codes and default messages across a module’s error paths
  • Producing descriptive “expected X, received Y” validation error messages
  • Differentiating handled vs unhandled errors in try/catch by using instanceof checks

Under The Hood

Architecture The core is a single-file factory (bin/error.js) exposing CustomError(name, parent, properties, factory), which returns a constructor closure; argument order is dynamically detected via a findArg helper paired with type-predicate functions (isNameArg/isParentArg/isPropertiesArg/isFactoryArg), so callers can pass any subset of the four parameters in any order. The prototype chain is built manually with Object.create(parent.prototype), and a CustomError metadata object (chain, factory, name, parent, properties) is attached to each prototype, with the chain array tracking ancestor factories for sequential invocation from root to leaf at instantiation. A companion bin/factories.js module supplies pluggable factory functions (root, expectReceive) invoked with the instance as this, each responsible for populating properties, defining getter/setter pairs for code/message, and generating a scoped stack trace. Changing the argument-order detection logic in findArg would break every consumer’s call signature, since it is the single point controlling how mixed-order arguments resolve.

Tech Stack Written in plain pre-ES2015 JavaScript (var, "use strict") with zero runtime dependencies, targeting CommonJS/Node (module.exports/require). The only dependency declared is a devDependency, chai ^3.4.1, used for test assertions. There is no bundler, transpiler, linter, or type-checker configured, package.json defines no scripts (no test script, no build step), and no CI configuration exists in the repository. The package’s main entry (index.js) simply re-exports bin/error.js, and the source totals roughly 15KB.

Code Quality The test suite (test/error.js) uses a Mocha-style describe/it structure with Chai’s expect assertions, covering constructor argument permutations, inheritance, naming, and factory behavior in reasonable depth — though without a package.json test script or CI workflow, nothing enforces that the suite actually runs. The library dogfoods its own error type internally: invalid argument ordering throws a CustomError.order instance rather than a generic Error. Naming is functional but terse (ar, props), the code relies on var and manual prototype manipulation instead of ES6 classes, and there is no TypeScript or systematic JSDoc coverage beyond a doc comment on the main entry function; no linter or formatter is configured.

API Design The API’s standout idea is order-independent arguments — CustomError(name, parent, properties, factory) accepts any subset of its four parameters in any order, inferred by type/shape via findArg, so callers can write CustomError('Foo'), CustomError(ParentError, {...}), or CustomError(factoryFn) without an options object. Custom errors are real constructor functions rather than plain objects or error codes, so instanceof works transparently through arbitrary inheritance depth, and the pluggable factory concept (CustomError.factory.root, .expectReceive) lets consumers customize how properties land on an instance without touching library internals. The README documents every parameter combination with runnable examples, though the mental model — chains, factories, property merging — takes some upfront learning before first productive use.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search