@test137e29b/errors
v1.2.1
Published
Shared error-handling primitives for Node.js services (HTTP errors, codes, NestJS filter)
Maintainers
Readme
@test137e29b/errors
Shared error-handling primitives that keep backend and frontend services aligned on error codes, HTTP status mappings, and serialisation rules.
Contents
- Installation
- What You Get
- Package Structure
- Getting Started
- API Highlights
- Development Workflow
- Testing
- Releasing
- License
Installation
npm install @test137e29b/errors
# or
yarn add @test137e29b/errorsNode.js >=22.14.0 is required. Use nvm use 22 (or your preferred tool) before running scripts to match the package engines.
What You Get
- A canonical
CustomErrorbase with strongly-typed HTTP status codes. - Drop-in subclasses for the most common HTTP error surfaces (
BadRequestError,UnauthorizedError,NotFoundError,UnprocessableError,InternalError). - A deterministic error-code generator that produces IDs such as
E-API-0001once you callsetErrorCodeLetters('API'). - Helpers for creating client-safe error payloads that never leak internal metadata.
The module is intentionally lightweight so downstream codebases can adopt the contract without pulling in unrelated auth or context logic.
Package Structure
Client Entry (@test137e29b/errors/client)
Currently ships an empty placeholder. Keep imports in place so that future browser-safe utilities (for example, client-side deserialisers) can land without sweeping refactors.
Common Entry (@test137e29b/errors/common)
Reserved for helpers that run in both Node and browser runtimes. The initial release exports nothing; add cross-environment code here to avoid coupling UI bundles to server-only files.
Server Entry (@test137e29b/errors/server)
The primary surface today. It re-exports the error classes and configuration helper defined under src/server/errors/**:
setErrorCodeLetters(prefix: string)— configure the three-letter prefix used by all generated error IDs.BadRequestError,UnauthorizedError,NotFoundError,UnprocessableError,InternalError— concrete subclasses ofCustomErrorwith baked-in HTTP status codes.GlobalErrorFilter— a NestJSBaseExceptionFilterderivative that converts any thrownCustomErrorinto a sanitised HTTP response.
Deeper utilities such as CustomError, createErrorResource, and isCustomError are available from path-based imports (@test137e29b/errors/server/errors/base, @test137e29b/errors/server/errors/types, etc.) when you need to extend the behaviour.
Getting Started
Set the error-code prefix once during application bootstrap, then throw rich errors from your service or controller layers.
import { BadRequestError, InternalError, setErrorCodeLetters } from '@test137e29b/errors/server';
enum ErrorCode {
InvalidPayload = 1,
DatabaseFailure = 2
}
setErrorCodeLetters('API');
export function validateInput(payload: unknown) {
if (!payload) {
throw new BadRequestError(ErrorCode.InvalidPayload, 'Request body is required', { hint: 'SENT_EMPTY_BODY' });
}
}
export async function saveRecord(data: unknown) {
try {
await persist(data);
} catch (error) {
throw new InternalError(ErrorCode.DatabaseFailure, 'Failed to save record', { data }, true, { originalError: error });
}
}Every subclass automatically produces a standardised code (for example E-API-0001) and sets the appropriate HTTP status so you do not have to repeat boilerplate.
API Highlights
HTTP Error Classes
BadRequestError— maps to HTTP 400. Accepts optionaldata,isRetryable, andinternalDatapayloads for richer diagnostics.UnauthorizedError— maps to HTTP 401. Designed for authentication/authorisation failures where client payloads are generally empty.NotFoundError— maps to HTTP 404. Use when a requested resource cannot be located.UnprocessableError— maps to HTTP 422 for validation scenarios that pass transport checks but fail business rules.InternalError— maps to HTTP 500. Suitable for unexpected server-side faults; passisRetryablewhen background jobs can safely retry.
All classes share the same constructor signature and inherit from CustomError, so you can instanceof against either the concrete type or the shared base.
Serialising For Clients
Use createErrorResource to build response payloads that omit internal diagnostics while still returning the canonical error details.
import { createErrorResource, isCustomError } from '@test137e29b/errors/server/errors/types';
export function toHttpResponse(err: unknown) {
if (isCustomError(err)) {
return {
status: err.httpCode,
body: createErrorResource(err)
};
}
return {
status: 500,
body: { message: 'Internal server error' }
};
}Because createErrorResource intentionally strips internalData, you can safely log the richer structure while returning the sanitised object to clients.
Runtime Type Guards
Inside this repository, guard helpers live under src/libs/typeGuards.ts. When extending the package, reuse those helpers (isArrayOf, isOptional, isDefined, etc.) and keep new guards pure so they can be shared across HTTP handlers, background jobs, and tests.
NestJS Integration
Drop the GlobalErrorFilter into your Nest bootstrap to centralise error serialisation. It will translate any CustomError (or subclass) into a consistent JSON payload while delegating everything else to Nest's default filter chain.
import { NestFactory } from '@nestjs/core';
import { HttpAdapterHost } from '@nestjs/core';
import { AppModule } from './app.module';
import { GlobalErrorFilter } from '@test137e29b/errors/server';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const { httpAdapter } = app.get(HttpAdapterHost);
app.useGlobalFilters(new GlobalErrorFilter(httpAdapter));
await app.listen(3000);
}
bootstrap();Development Workflow
npm install— install dependencies (Node>=22.14.0).npm run lint— run Prettier followed by ESLint with auto-fix.npm test— execute the Jest suite.npm run prepublishOnly— cleandist/and emit the TypeScript build.npm run audit-dependencies— execute the security audit (powered byaudit-ci).
Testing
npm test # run unit tests
npm test -- --coverage # optional coverage reportingAdd tests that mirror the runtime directory (tests/unit/server/errors/**) when introducing new error helpers to maintain confidence in the shared contract.
Releasing
- Confirm
npm run prepublishOnlypasses so the compiled artefacts are up to date. - Ensure the
exportsmap inpackage.jsononly surfaces supported entry points (client,common,server). - Tag releases with semantic versions (for example
v0.1.0). The package publishes privately via the scoped registry withaccess: restricted. - Authenticate using
NPM_TOKEN(or equivalent) before runningnpm publish.
License
Copyright test137E29B. All rights reserved. Internal use only. Redistribution outside test137E29B requires written permission.
