Typed, reusable application errors for JavaScript and TypeScript.
Create consistent errors with stable codes, typed causes, and reliable
instanceof checks. CommonJS and ES module entry points are included.
- Consistent error contracts — every error exposes a
message,code, optionalcause, and stack trace. - Useful built-in categories — start with common application, validation, authorization, and not-found errors.
- TypeScript-friendly — constructor options, causes, and specialized error data are typed.
- Easy to extend — derive domain-specific errors while retaining predictable behavior.
- Ready for APIs and logs — normalize an error into a serializable object when it needs to cross a process boundary.
npm install error-libUsing Yarn or pnpm
yarn add error-libpnpm add error-libimport {
ForbiddenError,
NotFoundError,
normalizeErrorObject,
} from 'error-lib';
function readDocument(documentId: string, canRead: boolean) {
if (!documentId) {
throw new NotFoundError('Document was not found');
}
if (!canRead) {
throw new ForbiddenError('You cannot access this document', {
code: 'E_DOCUMENT_ACCESS_DENIED',
});
}
return { id: documentId };
}
try {
readDocument('doc-123', false);
} catch (error) {
if (error instanceof ForbiddenError) {
console.error(error.code, error.message);
console.error(normalizeErrorObject(error));
} else {
throw error;
}
}CommonJS is supported through the package's require entry point:
const { ApplicationError, NotFoundError } = require('error-lib');All specialized errors inherit from ApplicationError, which itself extends the
native Error class.
| Export | Default code | Additional data |
|---|---|---|
ApplicationError |
E_APPLICATION_ERROR |
— |
BadRequestError |
E_BAD_REQUEST |
— |
ValidationError |
E_VALIDATION_FAILED |
validationError |
ForbiddenError |
E_FORBIDDEN |
— |
NotFoundError |
E_NOT_FOUND |
— |
ResourceNotFoundError |
E_RESOURCE_NOT_FOUND |
resourceId, resourceType |
RouteNotFoundError |
E_ROUTE_NOT_FOUND |
route, method |
Each constructor accepts an optional custom message and options containing a
custom code and typed cause. Specialized errors that carry extra data accept
that data before the message and options.
import { ResourceNotFoundError } from 'error-lib';
throw new ResourceNotFoundError(
'user-42',
'User',
'The requested user does not exist',
{ code: 'E_USER_NOT_FOUND' },
);Use cause to retain the error that led to the application error:
import { ApplicationError } from 'error-lib';
try {
await saveRecord();
} catch (cause) {
if (cause instanceof Error) {
throw new ApplicationError('Could not save the record', {
code: 'E_RECORD_SAVE_FAILED',
cause,
});
}
throw cause;
}Native error properties such as message and stack are not enumerable.
normalizeErrorObject copies them into a JSON-safe object for structured
logging or API responses.
import { NotFoundError, normalizeErrorObject } from 'error-lib';
const error = new NotFoundError('Order 123 was not found');
const payload = normalizeErrorObject(error);
console.log(JSON.stringify(payload));Extend the closest built-in error and provide a stable domain-specific code:
import {
BadRequestError,
BadRequestErrorConstructorOptions,
} from 'error-lib';
export class InvalidCredentialsError<
TCause extends Error = Error,
> extends BadRequestError<TCause> {
constructor(
message = 'The supplied credentials are invalid',
options?: BadRequestErrorConstructorOptions<TCause>,
) {
super(message, {
cause: options?.cause,
code: options?.code ?? 'E_INVALID_CREDENTIALS',
});
Error.captureStackTrace(this, InvalidCredentialsError);
Object.setPrototypeOf(this, InvalidCredentialsError.prototype);
}
}The custom error remains compatible with checks at every level of the hierarchy:
const error = new InvalidCredentialsError();
error instanceof InvalidCredentialsError; // true
error instanceof BadRequestError; // true
error instanceof Error; // truenpm ci
npm test
npm run buildBug reports and feature requests are welcome in GitHub Issues.
MIT © Danial Manavi
