API Error Handling

A lightweight, production-ready error handling utility for Express applications.

This component provides:

  • Standardized HTTP status codes
  • A typed ApiError class
  • Consistent, predictable error responses
  • Clear separation between operational and programmer errors

Installation Guide

This component requires additional Servercn components.

👉 You do not need to install any Servercn components manually. Running this component installer will automatically install all required components. Manual installation is optional and only recommended if you prefer fine-grained components control

npx servercn-cli add error-handler

Basic Implementation

MVC: src/utils/api-error.ts

Feature: src/shared/errors/api-error.ts

import { STATUS_CODES, StatusCode } from "../constants/status-codes";
 
export class ApiError extends Error {
  public readonly statusCode: StatusCode;
  public readonly isOperational: boolean;
  public readonly errors?: unknown;
 
  constructor(
    statusCode: StatusCode,
    message: string,
    errors?: unknown,
    isOperational = true
  ) {
    super(message);
    this.name = "ApiError";
    this.statusCode = statusCode;
    this.errors = errors;
    this.isOperational = isOperational;
 
    Error.captureStackTrace(this, this.constructor);
  }
 
  static badRequest(message = "Bad Request", errors?: unknown) {
    return new ApiError(STATUS_CODES.BAD_REQUEST, message, errors);
  }
 
  static unauthorized(message = "Unauthorized") {
    return new ApiError(STATUS_CODES.UNAUTHORIZED, message);
  }
 
  static forbidden(message = "Forbidden") {
    return new ApiError(STATUS_CODES.FORBIDDEN, message);
  }
 
  static notFound(message = "Not Found") {
    return new ApiError(STATUS_CODES.NOT_FOUND, message);
  }
 
  static conflict(message = "Conflict") {
    return new ApiError(STATUS_CODES.CONFLICT, message);
  }
 
  static validation(message = "Validation failed", errors?: unknown) {
    return new ApiError(STATUS_CODES.BAD_REQUEST, message, errors);
  }
 
  static notImplemented(message = "Not Implemented") {
    return new ApiError(STATUS_CODES.NOT_IMPLEMENTED, message);
  }
 
  static badGateway(message = "Bad Gateway") {
    return new ApiError(STATUS_CODES.BAD_GATEWAY, message);
  }
 
  static serviceUnavailable(message = "Service Unavailable") {
    return new ApiError(STATUS_CODES.SERVICE_UNAVAILABLE, message);
  }
 
  static tooManyRequests(message = "Too Many Requests") {
    return new ApiError(STATUS_CODES.TOO_MANY_REQUESTS, message);
  }
 
  static server(message = "Internal Server Error") {
    return new ApiError(STATUS_CODES.INTERNAL_SERVER_ERROR, message);
  }
}
 
/*
 * Usage:
 * throw new ApiError(STATUS_CODES.NOT_FOUND, "Not found");
 * throw ApiError.badRequest("Bad request");
 */

Usage Example

import { ApiError } from "../utils/api-error";
import { AsyncHandler } from "../utils/async-handler";
 
export const signinUser = AsyncHandler(async (req, res) => {
  const { email, password } = req.body;
 
  if (!email || !password) {
    throw ApiError.badRequest("Missing email or password");
  }
  // ...
});

Error Response

If email or password is missing, then return standardized responses:

{
  "success": false,
  "message": "Missing email or password",
  "statusCode": 400
}

File & Folder Structure

ServerCN

Select a file to view its contents

Installation

npx servercn-cli add error-handler