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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@smbcheeky/error-object-from-payload

v1.3.0

Published

Create ErrorObjects from any payload with simple rules and benefit from step-to-step debugging logs for the entire process.

Readme

License deno.bundlejs.com npm downloads GitHub last commit GitHub stars

ErrorObjectFromPayload

Create ErrorObject instances from any payload — API responses, caught exceptions, or unknown objects — using simple path-based rules. Get step-by-step debugging logs for the entire process.

TL;DR

npm install @smbcheeky/error-object @smbcheeky/error-object-from-payload
new ErrorObjectFromPayload(<any error-like payload>).debugLog('LOG');
// Use the debug output to understand what was found and adjust your options

Then check the playground for detailed, step-by-step examples.

Installation

npm install @smbcheeky/error-object @smbcheeky/error-object-from-payload
yarn add @smbcheeky/error-object @smbcheeky/error-object-from-payload

Both packages are required — ErrorObjectFromPayload extends ErrorObject.

Why This Package?

ErrorObject gives you structured, chainable errors. But when you're dealing with API responses, third-party payloads, or caught exceptions, you need a way to extract an error from messy, inconsistent data.

ErrorObjectFromPayload does that — you give it any object and a set of path-based rules, and it figures out the code, message, details, and domain. When something doesn't map correctly, the debug output tells you exactly what was found, where, and what went wrong.

Quick Start

import { ErrorObjectFromPayload } from '@smbcheeky/error-object-from-payload';

// Pass any error-like object — it just works with common patterns
new ErrorObjectFromPayload({
  error: { code: 'auth/invalid-email', message: 'The email address is badly formatted.' },
}).debugLog('LOG');

// [LOG] The email address is badly formatted. [auth/invalid-email]
// [DEBUG] { "code": "auth/invalid-email", "message": "The email address is badly formatted.", "raw": { ... } }

How It Works

ErrorObjectFromPayload processes your input based on ErrorObjectBuildOptions:

  1. Input validation — checks the input object using checkInputObjectForValues, checkInputObjectForTypes, and checkInputObjectForKeys. If a check fails, processing stops early.

  2. Error array detection — looks for an array at pathToErrors (e.g. ['errors']). If found, each element is processed separately and all other paths become relative to those elements.

  3. Value extraction — resolves pathToCode, pathToNumberCode, pathToMessage, pathToDetails, and pathToDomain against each error object. String values are kept as-is; arrays and objects are JSON.stringify'd.

  4. Transform — the optional transform function receives all extracted values and the source object, letting you remap codes to messages, derive domains, or apply any custom logic.

  5. Result — the first valid error (with both code and message) becomes the ErrorObjectFromPayload. Additional errors are stored in nextErrors. The raw property contains processingErrors, summary, and the original input for debugging.

Build Options

new ErrorObjectFromPayload(payload, {
  // Pre-checks — skip processing if the input doesn't match
  checkInputObjectForValues: { status: { value: 'error', exists: true } },
  checkInputObjectForTypes: { data: { type: 'object', exists: true } },
  checkInputObjectForKeys: { error: { exists: true } },

  // Path to an array of errors (paths become relative to each element)
  pathToErrors: ['errors', 'errs'],

  // Paths to error properties (first match wins)
  pathToCode: ['code', 'error.code'],
  pathToNumberCode: ['numberCode'],
  pathToMessage: ['message', 'error.message'],
  pathToDetails: ['details', 'error.details'],
  pathToDomain: ['domain', 'type'],

  // Transform extracted values before creating the error
  transform: (beforeTransform, inputObject) => ({
    ...beforeTransform,
    message: beforeTransform.code === 'timeout' ? 'Request timed out.' : beforeTransform.message,
  }),
});

All paths support dot notation for nesting (e.g. error.context.reason) and numeric indices for arrays (e.g. errors.0.code).

Default Options

The library ships with sensible defaults that cover common API error patterns:

{
  pathToErrors: ['errors', 'errs'],
  pathToCode: addPrefixPathVariants('error', ['code', 'err_code', 'errorCode', 'error_code']),
  pathToNumberCode: addPrefixPathVariants('error', ['numberCode', 'err_number_code', ...]),
  pathToMessage: addPrefixPathVariants('error', ['message', 'err_message', 'errorMessage', ...]),
  pathToDetails: addPrefixPathVariants('error', ['details', 'err_details', 'errorDetails', ...]),
  pathToDomain: addPrefixPathVariants('error', ['domain', 'errorDomain', 'type', ...]),
  transform: /* auto-converts numberCode to code string if code is missing */,
}

Use addPrefixPathVariants('error', ['code']) to generate ['code', 'error.code'] — handy when the error might be nested or at the root.

Logging

ErrorObjectFromPayload inherits all logging from ErrorObject and adds verboseLog():

error.log('TAG');        // toString() — message + code
error.debugLog('TAG');   // toDebugString() — includes full JSON with raw
error.verboseLog('TAG'); // toVerboseString() — debugLog + nextErrors (if any)

All methods return this for inline chaining.

Multiple Errors

When pathToErrors finds an array with multiple entries, the first becomes the main error and the rest are stored in nextErrors:

const error = new ErrorObjectFromPayload(
  {
    error: {
      errors: [
        { code: 'auth/invalid-email', message: 'The email address is badly formatted.' },
        { code: 'auth/weak-password', message: 'The password is too weak.' },
      ],
    },
  },
  { pathToErrors: ['error.errors'] },
);

error.debugLog('AUTH');
// [AUTH][1] The email address is badly formatted. [auth/invalid-email]
// [DEBUG] { ... }
// [AUTH][2] The password is too weak. [auth/weak-password]
// [DEBUG] { ... }

error.nextErrors; // [ErrorObjectFromPayload { code: 'auth/weak-password', ... }]

Debugging

When an error can't be built (missing code or message), ErrorObjectFromPayload returns a fallback error. Use .isFallback() to check and .debugLog() to see what went wrong:

const error = new ErrorObjectFromPayload(somePayload);

if (error.isFallback()) {
  error.debugLog('FALLBACK');
  // Check raw.processingErrors for what failed
  // Check raw.summary for what values were found at which paths
}

Static Configuration

// Show detailed console.log output during error building (default: true)
ErrorObjectFromPayload.SHOW_ERROR_LOGS = false;

// Show domain in toString() output (default: false, from ErrorObject 1.2.1)
ErrorObject.INCLUDE_DOMAIN_IN_STRING = true;

// Customize the log method
ErrorObject.LOG_METHOD = myLogger.error;

// Disable logging entirely
ErrorObject.LOG_METHOD = null;

Examples

Parse a REST API error

new ErrorObjectFromPayload(JSON.parse(response.body), {
  pathToNumberCode: ['code'],
  pathToMessage: ['error'],
}).debugLog('API');

// [API] Invalid input data [400]
// [DEBUG] { "code": "400", "numberCode": 400, "message": "Invalid input data", "raw": { ... } }

Map error codes to user-facing messages

const createAuthError = (code: string) =>
  new ErrorObjectFromPayload(
    { code, domain: 'auth' },
    {
      transform: (state) => {
        const messages: Record<string, string> = {
          'generic': 'Something went wrong',
          'generic-again': 'Something went wrong. Please try again.',
          'generic-network': 'Please check your internet connection.',
        };
        return { ...state, message: messages[state.code ?? ''] ?? 'Something went wrong.' };
      },
    },
  );

createAuthError('generic').log('1');         // [1] Something went wrong [auth/generic]
createAuthError('generic-again').log('2');   // [2] Something went wrong. Please try again. [auth/generic-again]
createAuthError('generic-network').log('3'); // [3] Please check your internet connection. [auth/generic-network]

Parse a GraphQL error response

new ErrorObjectFromPayload(
  {
    errors: [
      {
        message: 'Cannot query field "username" on type "User"',
        locations: [{ line: 2, column: 3 }],
        extensions: { code: 'GRAPHQL_VALIDATION_FAILED' },
      },
    ],
    data: null,
  },
  {
    pathToCode: ['extensions.code'],
    pathToMessage: ['message'],
    pathToDetails: ['locations'],
    checkInputObjectForValues: { data: { value: null, exists: true } },
  },
).debugLog('GQL');

// [GQL] Cannot query field "username" on type "User" [GRAPHQL_VALIDATION_FAILED]
// [DEBUG] { "code": "GRAPHQL_VALIDATION_FAILED", "message": "...", "details": "[{...}]", "raw": { ... } }

FAQ

Are paths absolute or relative?

Paths start as absolute (from the input root). If pathToErrors finds an array, all other paths become relative to each element in that array. You can either set pathToErrors to [] and map from the root, or keep it and use relative paths — the second approach is recommended as it handles multiple errors automatically.

The error code is sometimes in error.code and sometimes at the root...

Use addPrefixPathVariants('error', ['code']) to generate ['code', 'error.code'] — the first match wins.

Can I extract a raw value and process it later?

Yes. Use dot notation for any nesting depth (e.g. error.details.0). Non-string values are JSON.stringify'd. Use the transform function to parse or reshape them. An ErrorObject needs at least code and message as strings.

What's the difference between ErrorObject and ErrorObjectFromPayload?

Use new ErrorObject(...) when you know the code and message upfront. Use new ErrorObjectFromPayload(...) when you need to extract them from an unknown payload. Both are instanceof Error and instanceof ErrorObject.

More Examples

See the playground for 12 runnable examples covering GraphQL errors, REST APIs, nested payloads, validation errors, and more.