Open-Source Wikis

/

Node.js

/

Systems

/

Errors and validators

nodejs/node

Errors and validators

Purpose

Centralize how Node throws errors and validates arguments. Every error thrown by core has a stable, documented code (e.g. ERR_INVALID_ARG_TYPE). Every public-API argument check goes through lib/internal/validators.js. This makes user-facing errors consistent and gives downstream code something stable to match on.

Directory layout

lib/internal/
  errors.js                   // The error-class registry (codes, classes, messages)
  validators.js               // validate* helpers
src/
  node_errors.{cc,h}          // C++ side: throw-friendly helpers + JS-error codes
  node_errors.cc              // implementations + V8 message hooks
doc/api/
  errors.md                   // canonical doc: lists every code with stability

Key abstractions

Type / file Role
errorCodes (lib/internal/errors.js) Map of ERR_xxx → class with .code/.name/.message.
E(code, msgOrFn, baseClass) (lib/internal/errors.js) Helper used to register each error code.
validateString(...), validateInteger(...), etc. (lib/internal/validators.js) Throw consistent ERR_INVALID_ARG_TYPE/ERR_OUT_OF_RANGE.
THROW_ERR_* macros (src/node_errors.h) C++ helpers that throw the matching JS error.
errors::TriggerUncaughtException (src/node_errors.cc) Funnel for uncaught exceptions; honours --abort-on-uncaught-exception.

How errors are defined

Inside lib/internal/errors.js:

E(
  'ERR_INVALID_ARG_TYPE',
  (name, expected, actual) => {
    // detailed message construction
  },
  TypeError
);

E(
  'ERR_OUT_OF_RANGE',
  (str, range, input, replaceDefaultBoolean = false) => {
    /* ... */
  },
  RangeError
);

E('ERR_FS_FILE_TOO_LARGE', 'File size (%s) is greater than 2 GiB', RangeError);

E(code, msg, base) creates a class extending base (Error/TypeError/RangeError/SyntaxError/URIError) with a frozen .code, a deterministic message format, and registers it on codes.

Use:

const {
  codes: { ERR_INVALID_ARG_TYPE },
} = require('internal/errors');
throw new ERR_INVALID_ARG_TYPE('options.signal', 'AbortSignal', signal);

The same machinery lets process.on('uncaughtException') and stack frames carry the code in error.code so tests and user code can match on it.

How validators are used

lib/internal/validators.js exports the canonical validators:

Validator Throws when
validateString(value, name) value is not a string
validateNumber(value, name, min, max) not a number, or out of inclusive range
validateInteger(value, name, min, max) not a safe integer in range
validateBoolean(value, name) not a boolean
validateFunction(value, name) not callable
validateObject(value, name, options) not a plain object (with options for null/array allowance)
validateArray(value, name, minLength) not an array, or too short
validateBuffer(buf, name) not a Buffer/typed-array
validatePort(port, name) not a valid TCP/UDP port
validateAbortSignal(signal, name) not an AbortSignal
validateOneOf(value, name, choices) value not in choices
validateInt32/validateUint32 etc. range/bit-width checks

The convention: validate at the top of every public method; never validate inside hot loops or in private helpers that have already been validated.

C++ errors

src/node_errors.h provides macros mirroring the JS codes:

THROW_ERR_INVALID_ARG_TYPE(env, "expected string");
return THROW_ERR_OUT_OF_RANGE(env, "...");

Each macro creates a JS error with the matching code so a JS-side try { ... } catch (e) { e.code === 'ERR_OUT_OF_RANGE' } keeps working when the throw happens from C++.

errors::TriggerUncaughtException is the central choke point for uncaught exceptions — if you want to break in a debugger when any exception escapes JS, set a breakpoint there.

Integration points

  • util.format/util.inspect — error messages are formatted using primordial-safe helpers; do not call .toString() on user objects directly.
  • process.emitWarning — for non-fatal cases. Implementation: lib/internal/process/warning.js.
  • AbortError — special-cased class for AbortSignal cancellation.
  • SystemError — wraps libuv/syscall errors with errno, syscall, path, dest. Created in lib/internal/errors.js#hideStackFrames(SystemError).

Entry points for modification

  • New error code? Add an E(...) entry in lib/internal/errors.js, document it in doc/api/errors.md, and write at least one test that asserts err.code.
  • Tightening or relaxing an existing message? Errors are part of the public API — message changes go through a deprecation cycle. The stability levels are documented next to each code in doc/api/errors.md.
  • Adding a C++ error helper? src/node_errors.h ERRORS_WITH_CODE and PREDEFINED_ERROR_MESSAGES macros are the registry; don't bypass them.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Errors and validators – Node.js wiki | Factory