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

error-message-utils

v1.2.14

Published

The error-message-utils package simplifies error management in your web applications and RESTful APIs. It ensures consistent and scalable handling of error messages, saving you time and effort. Moreover, it gives you the ability to assign custom error cod

Downloads

10,717

Readme

Error Message Utils

error-message-utils helps TypeScript and JavaScript apps turn unknown errors into a consistent shape:

  • a readable message
  • a stable error code
  • optional extra data
  • an optional native error cause

Use Exception for most application code. Use encodeError and decodeError when you need to send or receive an error code inside a plain string.

Install

npm i -S error-message-utils

Recommended Usage: Exception

Exception is an Error subclass that stores a normalized message, a code, optional data, and an optional native cause.

import { Exception } from 'error-message-utils';

throw new Exception('The provided email is already in use.', 'EMAIL_EXISTS', {
  field: 'email',
});
const exception = new Exception('Request failed', 'REQUEST_FAILED');

exception instanceof Error; // true
exception instanceof Exception; // true
exception.name; // 'Exception'
exception.message; // 'Request failed'
exception.code; // 'REQUEST_FAILED'
exception.data; // null
exception.cause; // undefined
exception.toString(); // 'Request failed{(REQUEST_FAILED)}'
exception.toRecord();
// {
//   message: 'Request failed',
//   code: 'REQUEST_FAILED',
//   data: null,
// }

Preserve an Error Cause

When wrapping an error, provide a stable contextual message and pass the original value through the fourth IErrorOptions argument. This keeps the top-level message predictable while preserving the original error for debugging.

import { Exception, extractMessage } from 'error-message-utils';

try {
  await sendReceiptEmail();
} catch (cause) {
  const exception = new Exception(
    'Unable to send the receipt email.',
    'RECEIPT_EMAIL_FAILED',
    { operation: 'sendReceiptEmail' },
    { cause },
  );

  exception.message; // 'Unable to send the receipt email.'
  exception.cause === cause; // true
  extractMessage(exception); // combines the message with a truthy cause chain

  throw exception;
}

IErrorOptions is a direct alias of the native ErrorOptions type. This API requires the ES2022 TypeScript lib and a runtime that supports Error causes.

The existing new Exception(error, code, data) form remains supported. It normalizes the first argument into the exception message but does not infer or store that argument as cause. Avoid also appending the cause message to the top-level message because extractMessage already combines truthy cause chains. Native Error semantics still retain falsy causes such as false, 0, an empty string, or null, but extractMessage does not append them.

toString() and toRecord() intentionally omit cause. A cause can contain internal or sensitive details, so inspect or expose it only at an appropriate boundary.

Extend Exception

Create small domain-specific exception classes when your app has a stable set of error codes.

import { Exception, type IErrorOptions } from 'error-message-utils';

const USER_ERROR_CODES = {
  EmailTaken: 'USER_EMAIL_TAKEN',
  Unauthorized: 'USER_UNAUTHORIZED',
} as const;

type IUserErrorCode = (typeof USER_ERROR_CODES)[keyof typeof USER_ERROR_CODES];

export class UserException extends Exception {
  public constructor(
    message: string,
    code: IUserErrorCode,
    data?: unknown,
    options?: IErrorOptions,
  ) {
    super(message, code, data, options);
    this.name = 'UserException';
  }
}

throw new UserException(
  'The provided email is already in use.',
  USER_ERROR_CODES.EmailTaken,
  { field: 'email' },
);

Common Tasks

Extract a Message

extractMessage accepts any value and returns the best readable message it can find.

import { extractMessage } from 'error-message-utils';

extractMessage(
  new Error('Top level error', {
    cause: new Error('First nested cause', {
      cause: new Error('Second nested cause'),
    }),
  }),
);
// 'Top level error; [CAUSE]: First nested cause; [CAUSE]: Second nested cause'

extractMessage({
  message: {
    err: {
      message: 'This error message is nested deeply!',
    },
  },
});
// 'This error message is nested deeply!'

Zod errors are formatted with their first issue message and path.

import { z } from 'zod';
import { extractMessage } from 'error-message-utils';

const result = z.object({ name: z.string() }).safeParse({ name: 123 });

if (!result.success) {
  extractMessage(result.error);
  // 'Invalid input: expected string, received number (name)'
}

Redact Sensitive Values

extractRedactedMessage extracts a message using the same rules as extractMessage, then replaces every exact sensitive value with [redacted].

import { extractRedactedMessage } from 'error-message-utils';

const error = new Error('Request failed for token abc123.', {
  cause: new Error('The provider rejected abc123.'),
});

extractRedactedMessage(error, ['abc123']);
// 'Request failed for token [redacted].; [CAUSE]: The provider rejected [redacted].'

extractRedactedMessage(error, ['different-value']);
// 'Request failed for token abc123.; [CAUSE]: The provider rejected abc123.'

Matching is literal and case-sensitive. Empty values are ignored. The function does not automatically identify secrets, so transformed or encoded versions must be supplied separately if they also need redaction.

Get an Error Code

Use getErrorCode when you only need the resolved code.

import { Exception, getErrorCode } from 'error-message-utils';

const exception = new Exception('Access denied', 'ACCESS_DENIED');

getErrorCode(exception); // 'ACCESS_DENIED'
getErrorCode('Access denied'); // null

Use hasErrorCode when you want a direct boolean check.

import { Exception, hasErrorCode } from 'error-message-utils';

const exception = new Exception('Access denied', 'ACCESS_DENIED');

hasErrorCode(exception, 'ACCESS_DENIED'); // true
hasErrorCode(exception, 'PAYMENT_FAILED'); // false

Use hasErrorCodePrefix when related string codes share a prefix. Empty prefixes and numeric codes do not match.

import { Exception, hasErrorCodePrefix } from 'error-message-utils';

const exception = new Exception('User not found', 'USER_NOT_FOUND');

hasErrorCodePrefix(exception, 'USER_'); // true
hasErrorCodePrefix('USER_NOT_FOUND', 'USER_'); // true
hasErrorCodePrefix(exception, 'PAYMENT_'); // false

Encode and Decode Plain Strings

encodeError and decodeError are lower-level helpers for systems that can only pass string messages.

import { decodeError, encodeError } from 'error-message-utils';

const encodedError = encodeError(
  'The provided email is already in use.',
  'EMAIL_EXISTS',
);

encodedError;
// 'The provided email is already in use.{(EMAIL_EXISTS)}'

decodeError(encodedError);
// {
//   message: 'The provided email is already in use.',
//   code: 'EMAIL_EXISTS',
//   data: null,
// }

Detect Resolved Codes with isEncodedError

isEncodedError returns true when an error resolves to a non-default code. For direct code inspection, prefer getErrorCode or hasErrorCode.

import { encodeError, isEncodedError } from 'error-message-utils';

isEncodedError('Some random unencoded error'); // false
isEncodedError(new Error('Some random unencoded error')); // false
isEncodedError(encodeError('Some unknown error.', 'UNKNOWN_ERROR')); // true

Check the Default Message

Use isDefaultErrorMessage to detect the fallback message returned when no useful message can be extracted.

import { DEFAULT_MESSAGE, isDefaultErrorMessage } from 'error-message-utils';

isDefaultErrorMessage(DEFAULT_MESSAGE); // true
isDefaultErrorMessage(`${DEFAULT_MESSAGE} More details.`); // true
isDefaultErrorMessage(`${DEFAULT_MESSAGE} More details.`, true); // false

Public API

Import public items from the package root:

import {
  DEFAULT_CODE,
  DEFAULT_MESSAGE,
  Exception,
  decodeError,
  encodeError,
  extractMessage,
  extractRedactedMessage,
  getErrorCode,
  hasErrorCode,
  hasErrorCodePrefix,
  isDefaultErrorMessage,
  isEncodedError,
  type IDecodedError,
  type IErrorCode,
  type IErrorCodeCarrier,
  type IErrorOptions,
  type IExceptionRecord,
} from 'error-message-utils';

Classes

| Export | Description | | --- | --- | | Exception | An Error subclass that normalizes an unknown error into message, code, and data, and accepts native error options such as cause. It can also serialize itself with toString() or toRecord(), which omit the cause. |

Functions

| Export | Signature | Description | | --- | --- | --- | | extractMessage | (error: unknown) => string | Extracts the best readable message from strings, Error instances, nested error-like objects, Error.cause chains, arrays, plain objects, and Zod errors. Returns DEFAULT_MESSAGE when no useful message can be extracted. | | extractRedactedMessage | (error: unknown, sensitiveValues: readonly string[]) => string | Extracts a message and replaces every exact, case-sensitive occurrence of each non-empty sensitive value with [redacted]. Returns the extracted message unchanged when no value matches. | | encodeError | (error: unknown, code: IErrorCode) => string | Extracts a message from error and appends the wrapped code at the end of the message. | | decodeError | (error: unknown) => IDecodedError | Extracts a message, resolves a code from an encoded message or code-carrying object, and returns { message, code, data }. | | isEncodedError | (error: unknown) => boolean | Returns true when decodeError(error).code resolves to a non-default code. | | getErrorCode | (error: unknown) => IErrorCode \| null | Returns the resolved non-default code, or null when no non-default code is found. | | hasErrorCode | (error: unknown, code: IErrorCode) => boolean | Checks whether an error resolves to the provided code. Raw code values are compared with strict equality. | | hasErrorCodePrefix | (error: unknown, prefix: string) => boolean | Checks whether an error resolves to a string code that starts with the provided non-empty prefix. Raw string codes are supported; numeric codes do not match. | | isDefaultErrorMessage | (value: string, fullMatch?: boolean) => boolean | Checks whether a string contains DEFAULT_MESSAGE. Pass true as the second argument to require an exact match. |

Types

type IErrorCode = string | number;

type IErrorOptions = ErrorOptions;

type IDecodedError = {
  message: string;
  code: IErrorCode;
  data: unknown | null;
};

type IErrorCodeCarrier = {
  code: IErrorCode;
} & Record<string, unknown>;

type IExceptionRecord = {
  message: string;
  code: IErrorCode;
  data: unknown | null;
};

| Export | Description | | --- | --- | | IErrorCode | The supported type for application error codes. | | IErrorOptions | A direct alias of the native ErrorOptions type accepted by the Exception constructor. | | IDecodedError | The object returned by decodeError. | | IErrorCodeCarrier | A plain object shape that can provide a code to decodeError, getErrorCode, hasErrorCode, hasErrorCodePrefix, and Exception. | | IExceptionRecord | The serializable object returned by Exception.toRecord(). It does not include cause. |

Constants

const DEFAULT_CODE = -1;

const DEFAULT_MESSAGE =
  'The error message could not be extracted, check the logs for more information.';

| Export | Description | | --- | --- | | DEFAULT_CODE | The fallback code used when no code can be resolved. | | DEFAULT_MESSAGE | The fallback message used when no readable message can be extracted. |

Running Tests

npm test

License

MIT