forge-error
TypeScript icon, indicating that this package has built-in type declarations

0.0.4 • Public • Published

forge-error

A comprehensive and type-safe HTTP error handling library for Node.js and TypeScript applications. forge-error provides a structured, standardized, and consistent approach to defining, throwing, and handling HTTP errors with minimal boilerplate code. With fully typed error classes and built-in support for standardized error responses, it helps you write cleaner, more maintainable error handling logic in your application.

Table of Contents

  1. Installation

  2. Features

  3. Usage

  4. Error Classes

  5. Utilities

  6. Error Payload Structure

  7. Built-in Error Constants

Installation

npm install forge-error
# or
yarn add forge-error
# or
pnpm add forge-error

Features

  • Full suite of HTTP error classes (4xx and 5xx)
  • Standardized error payload structure
  • First-class TypeScript support
  • Custom error code and data support
  • Utility functions to handle, format, and inspect errors
  • Seamless integration with Express.js
  • Async controller wrapper for concise error handling

Usage

Creating Errors

You can create errors using one of the built-in error classes or create fully custom errors with ForgeError.

Using a Simple String

import { NotFoundError } from 'forge-error';

throw new NotFoundError('Resource not found');

Using a Detailed Object

import { BadRequestError } from 'forge-error';

throw new BadRequestError({
  message: 'Invalid input data',
  data: {
    field: 'email',
    issue: 'Invalid format'
  },
  errorCode: 'INVALID_EMAIL'
});

Creating a Custom Error

import { ForgeError } from 'forge-error';

throw new ForgeError(
  'Custom error occurred',
  418,
  'CUSTOM_ERROR_CODE',
  { additional: 'context' }
);

Express Integration

You can easily integrate forge-error with your Express.js application to return consistent error responses.

Wrapping Async Controllers

Use handleAsyncRequest to wrap controller logic and eliminate manual try-catch blocks:

import express, { Request, Response } from 'express';
import { handleAsyncRequest } from 'forge-error';

const app = express();

app.post('/login', handleAsyncRequest(async (req: Request, res: Response) => {
  // Your logic here
  res.status(200).json({ message: 'Login successful' });
}));

You can also export wrapped handlers:

// controllers/auth.controller.ts
app.post('/login', loginController);

const loginController = handleAsyncRequest(async (req, res) => {
  // Logic here
});

Global Error Handler

Use getForgeErrorPayload to build standardized error responses in your global error middleware:

const app = express();

app.use(routes)

app.use((error, req, res, next) => {
  const { statusCode, errorCode, message, data } = getForgeErrorPayload(error);

  res.status(statusCode).json({
    success: false,
    statusCode,
    errorCode,
    message,
    ...(data ? { data } : {})
  });
});

app.use((req, res) => {
  res.status(404).json({
    success: false,
    statusCode: 404,
    errorCode: 'NOT_FOUND',
    message: 'Resource not found'
  });
})
import { ErrorRequestHandler } from 'express';
import { getForgeErrorPayload } from 'forge-error';

const errorHandler: ErrorRequestHandler = (err, req, res, next) => {
  const { statusCode, errorCode, message, data } = getForgeErrorPayload(err);

  res.status(statusCode).json({
    success: false,
    statusCode,
    errorCode,
    message,
    ...(data ? { data } : {})
  });
};

export { errorHandler };

Error Classes

The library provides predefined error classes corresponding to standard HTTP status codes.

Client Errors (4xx)

import {
  BadRequestError,           // 400
  UnauthorizedError,         // 401
  ForbiddenError,            // 403
  NotFoundError,             // 404
  MethodNotAllowedError,     // 405
  NotAcceptableError,        // 406
  ConflictError,             // 409
  // ... and more
} from 'forge-error';

Server Errors (5xx)

import {
  InternalServerError,       // 500
  NotImplementedError,       // 501
  BadGatewayError,           // 502
  ServiceUnavailableError,   // 503
  GatewayTimeoutError,       // 504
  // ... and more
} from 'forge-error';

Utilities

The package provides several utility functions to handle error payloads. These are divided into two categories:

Type-Specific Utilities (Return undefined for non-matching errors)

import { getErrorPayload, getClientErrorPayload, getServerErrorPayload } from 'forge-error';

// 1. Get payload for any forge error
const error1 = new NotFoundError('Resource not found');
const payload1 = getErrorPayload(error1);
// Returns: { message: 'Resource not found', statusCode: 404, errorCode: 'NOT_FOUND' }

const error2 = new Error('Regular error');
const payload2 = getErrorPayload(error2);
// Returns: undefined

// 2. Get payload only for client errors (4xx)
const clientError = new NotFoundError('Not found');
const clientPayload = getClientErrorPayload(clientError);
// Returns: { message: 'Not found', statusCode: 404, errorCode: 'NOT_FOUND' }

const serverError = new InternalServerError('Server error');
const wrongPayload = getClientErrorPayload(serverError);
// Returns: undefined

// 3. Get payload only for server errors (5xx)
const serverPayload = getServerErrorPayload(serverError);
// Returns: { message: 'Server error', statusCode: 500, errorCode: 'INTERNAL_SERVER_ERROR' }

Guaranteed Payload Utilities (Always return a payload)

import { 
  getForgeClientErrorPayload, 
  getForgeServerErrorPayload, 
  getForgeErrorPayload 
} from 'forge-error';

// 1. Always get a client error payload
const error = new Error('Unknown error');
const clientPayload = getForgeClientErrorPayload(error);
// Returns: { 
//   message: 'Unknown error', 
//   statusCode: 400,          // Default client error status
//   errorCode: 'BAD_REQUEST'  // Default client error code
// }

// 2. Always get a server error payload
const serverPayload = getForgeServerErrorPayload(error);
// Returns: {
//   message: 'Unknown error',
//   statusCode: 500,                  // Default server error status
//   errorCode: 'INTERNAL_SERVER_ERROR' // Default server error code
// }

// 3. Always get a generic error payload (uses server error defaults)
const genericPayload = getForgeErrorPayload(error);
// Returns: {
//   message: 'Unknown error',
//   statusCode: 500,
//   errorCode: 'INTERNAL_SERVER_ERROR'
// }

// Common usage in Express error handler:
app.use((error, req, res, next) => {
  // Will always return a valid error response
  const { statusCode, ...payload } = getForgeErrorPayload(error);
  res.status(statusCode).json(payload);
});
import { isClientError, isServerError, isBaseError } from 'forge-error';

const error = new NotFoundError('Resource not found');

isClientError(error);  // true
isServerError(error);  // false
isBaseError(error);    // true

Error Payload Structure

All forge errors return a standardized structure:

{
  message: string;      // Human-readable error message
  statusCode: number;   // HTTP status code
  errorCode: string;    // Error identifier
  data?: object;        // Optional additional context
}

This format is useful for consistent API responses, logging, and debugging.

Error Handling Example

try {
  // Your code here
  throw new BadRequestError('Invalid input');
} catch (error) {
  if (error instanceof BadRequestError) {
    const payload = error.buildErrorPayload();
    // Handle the error with standardized payload
    console.log(payload);
    /*
    {
      message: 'Invalid input',
      statusCode: 400,
      errorCode: 'BAD_REQUEST'
    }
    */
  }
}

Built-in Error Constants

The library includes a comprehensive set of predefined HTTP error types with their default values. You can override these defaults using a detailed object.

Error Class Status Code Error Code Default Message
4xx Client Errors
BadRequestError 400 BAD_REQUEST The request could not be processed due to invalid syntax or parameters
UnauthorizedError 401 UNAUTHORIZED Authentication is required to access this resource
PaymentRequiredError 402 PAYMENT_REQUIRED Payment is required to access this resource
ForbiddenError 403 FORBIDDEN You do not have permission to access this resource
NotFoundError 404 NOT_FOUND The requested resource could not be found
MethodNotAllowedError 405 METHOD_NOT_ALLOWED The requested HTTP method is not allowed for this resource
NotAcceptableError 406 NOT_ACCEPTABLE The requested content type cannot be served by this resource
ProxyAuthenticationRequiredError 407 PROXY_AUTHENTICATION_REQUIRED Proxy server authentication is required
RequestTimeoutError 408 REQUEST_TIMEOUT The server timed out waiting for the request
ConflictError 409 CONFLICT The request conflicts with the current state
GoneError 410 GONE The requested resource is no longer available
LengthRequiredError 411 LENGTH_REQUIRED Content-Length header is required
PreconditionFailedError 412 PRECONDITION_FAILED One or more conditions failed
PayloadTooLargeError 413 PAYLOAD_TOO_LARGE Request payload exceeds the limit
URITooLongError 414 URI_TOO_LONG Request URI exceeds the maximum length
UnsupportedMediaTypeError 415 UNSUPPORTED_MEDIA_TYPE The content type is not supported
RangeNotSatisfiableError 416 RANGE_NOT_SATISFIABLE The requested range cannot be satisfied
ExpectationFailedError 417 EXPECTATION_FAILED Server cannot meet the requirements
TeapotError 418 IM_A_TEAPOT I'm a teapot
SessionExpiredError 419 SESSION_EXPIRED Your session has expired. Please refresh and try again
RateLimitError 420 RATE_LIMIT_EXCEEDED Request rate limit has been exceeded
MisdirectedRequestError 421 MISDIRECTED_REQUEST The request was sent to a server unable to produce a response
UnprocessableEntityError 422 UNPROCESSABLE_ENTITY The request was well-formed but invalid
LockedError 423 RESOURCE_LOCKED The requested resource is currently locked
FailedDependencyError 424 FAILED_DEPENDENCY The request failed due to the failure of a previous request
TooEarlyError 425 TOO_EARLY The server is not ready to process the request
UpgradeRequiredError 426 UPGRADE_REQUIRED Client must upgrade to a different protocol version
PreconditionRequiredError 428 PRECONDITION_REQUIRED This request requires preconditions to be specified
TooManyRequestsError 429 TOO_MANY_REQUESTS Rate limit exceeded
RequestHeaderFieldsTooLargeError 431 REQUEST_HEADERS_TOO_LARGE Request header fields exceed maximum size
NoResponseError 444 NO_RESPONSE Server returned no information and closed the connection
RetryWithError 449 RETRY_WITH The request should be retried after performing the appropriate action
BlockedByWindowsParentalControlsError 450 BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS Access denied by Windows parental controls
LegallyRestrictedError 451 LEGALLY_RESTRICTED Access denied for legal reasons
RequestHeaderTooLargeError 494 REQUEST_HEADER_TOO_LARGE Request header is too large
SSLCertificateError 495 SSL_CERTIFICATE_ERROR SSL/TLS certificate validation error
SSLCertificateRequiredError 496 SSL_CERTIFICATE_REQUIRED A valid SSL/TLS certificate is required
HTTPRequestSentToHTTPSPortError 497 HTTP_REQUEST_SENT_TO_HTTPS_PORT An HTTP request was sent to an HTTPS port
InvalidTokenError 498 INVALID_TOKEN The token provided is invalid or has expired
TokenRequiredError 499 TOKEN_REQUIRED A valid token is required to access this resource
ClientClosedRequestError 499 CLIENT_CLOSED_REQUEST Client closed the request before the server could respond
5xx Server Errors
InternalServerError 500 INTERNAL_SERVER_ERROR An unexpected error occurred
NotImplementedError 501 NOT_IMPLEMENTED Not implemented
BadGatewayError 502 BAD_GATEWAY Invalid response from upstream server
ServiceUnavailableError 503 SERVICE_UNAVAILABLE Service temporarily unavailable
GatewayTimeoutError 504 GATEWAY_TIMEOUT Gateway timeout
HTTPVersionNotSupportedError 505 HTTP_VERSION_NOT_SUPPORTED HTTP version not supported
VariantAlsoNegotiatesError 506 VARIANT_ALSO_NEGOTIATES Server configuration error in content negotiation
InsufficientStorageError 507 INSUFFICIENT_STORAGE Insufficient storage space to complete the request
LoopDetectedError 508 LOOP_DETECTED Request processing stopped due to infinite loop detection
BandwidthLimitExceededError 509 BANDWIDTH_LIMIT_EXCEEDED Server bandwidth limit has been exceeded
NotExtendedError 510 NOT_EXTENDED Server requires additional extensions to fulfill the request
NetworkAuthenticationRequiredError 511 NETWORK_AUTHENTICATION_REQUIRED Network authentication is required

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Package Sidebar

Install

npm i forge-error

Weekly Downloads

311

Version

0.0.4

License

ISC

Unpacked Size

114 kB

Total Files

24

Last publish

Collaborators

  • pavanguptaz