ExisJS

exisjs/error

The exisjs/error module provides the standardized HTTP exception hierarchy, factory helpers, error file convention handlers, and terminal diagnostic formatters.


Module Exports

import {  // Base & Error Classes  HttpError,  BadRequestError,  UnauthorizedError,  ForbiddenError,  NotFoundError,  ConflictError,  PayloadTooLargeError,  UnprocessableError,  RateLimitError,  InternalError,
  // Exception Aliases  HttpException,  BadRequestException,  UnauthorizedException,  ForbiddenException,  NotFoundException,  ConflictException,  PayloadTooLargeException,  UnprocessableException,  RateLimitException,  InternalException,
  // Handlers & Pipeline  createErrorHandler,  asyncHandler,
  // Error Diagnostic & Formatting Utilities  stripInternalStackFrames,  categorizeError,  generateErrorHint,  parseErrorLocation,  buildCodeFrame,  renderDevErrorToString,  formatDevError,  formatCliError,  devErrorResponse,} from 'exisjs/error'
import type { ParsedError } from 'exisjs/error'

1. HttpError Base Class

All framework exceptions inherit from HttpError.

export class HttpError extends Error {  public readonly statusCode: number  public readonly code: string  public readonly isOperational: boolean  public readonly details?: unknown
  constructor(    message: string,    statusCode = 500,    code = 'INTERNAL_ERROR',    details?: unknown  )}

Static Factory Methods

Factory MethodStatus CodeDefault CodeDefault Message
HttpError.badRequest(msg, details?)400'BAD_REQUEST'Required
HttpError.unauthorized(msg?)401'UNAUTHORIZED''Unauthorized'
HttpError.forbidden(msg?)403'FORBIDDEN''Forbidden'
HttpError.notFound(resource?)404'NOT_FOUND''Resource not found'
HttpError.conflict(msg)409'CONFLICT'Required
HttpError.payloadTooLarge(msg?, details?)413'PAYLOAD_TOO_LARGE''Payload too large'
HttpError.unprocessable(msg, details?)422'UNPROCESSABLE_ENTITY'Required
HttpError.tooManyRequests(msg?)429'TOO_MANY_REQUESTS''Too many requests'
HttpError.internal(msg?)500'INTERNAL_ERROR''Internal server error'
HttpError.serviceUnavailable(msg?)503'SERVICE_UNAVAILABLE''Service unavailable'

2. Exception Classes Catalog

Each exception class can be instantiated directly with new and has an equivalent *Exception alias:

Error ClassAliasStatus CodeDefault Code
BadRequestErrorBadRequestException400'BAD_REQUEST'
UnauthorizedErrorUnauthorizedException401'UNAUTHORIZED'
ForbiddenErrorForbiddenException403'FORBIDDEN'
NotFoundErrorNotFoundException404'NOT_FOUND'
ConflictErrorConflictException409'CONFLICT'
PayloadTooLargeErrorPayloadTooLargeException413'PAYLOAD_TOO_LARGE'
UnprocessableErrorUnprocessableException422'UNPROCESSABLE_ENTITY'
RateLimitErrorRateLimitException429'TOO_MANY_REQUESTS'
InternalErrorInternalException500'INTERNAL_ERROR'

3. Usage Examples

Functional Route Example

src/http/users/route.ts
import { controller, route } from 'exisjs/router'import { HttpError, NotFoundException } from 'exisjs/error'
export default controller({  getById: route.get('/:id', {    async handle({ params }) {      const user = await findUser(params.id)      if (!user) {        throw new NotFoundException(`User with ID ${params.id} not found`)      }      return user    },  }),})

Class-Based Controller Example

src/http/users/route.ts
import { Controller, Get, Param } from 'exisjs/decorators'import { HttpError } from 'exisjs/error'
@Controller('/users')export default class UserController {  @Get('/:id')  async getById(@Param('id') id: string) {    const user = await findUser(id)    if (!user) {      throw HttpError.notFound('User')    }    return user  }}

4. Custom Application Exceptions

Custom domain exceptions can be constructed by extending HttpError:

src/errors/payment.ts
import { HttpError } from 'exisjs/error'
export class InsufficientBalanceError extends HttpError {  constructor(required: number, current: number) {    super(      'Insufficient balance to complete transaction',      402,      'INSUFFICIENT_BALANCE',      { required, current }    )  }}

5. Global Error Handling Convention (src/http/error.ts)

ExisJS auto-discovers and mounts src/http/error.ts to centralize application error interceptors:

Functional Style

src/http/error.ts
import type { Request, Response } from 'exisjs'
export function onError(err: any, req: Request, res: Response): void | Promise<void> {  const status = err.statusCode || err.status || 500  res.status(status).json({    success: false,    error: {      code: err.code || 'INTERNAL_ERROR',      message: err.message || 'An unexpected error occurred',      path: req.path,    },  })}

Class-Based Style

src/http/error.ts
import type { Request, Response } from 'exisjs'
export default class GlobalErrorHandler {  onError(err: any, req: Request, res: Response): void | Promise<void> {    const status = err.statusCode || err.status || 500    res.status(status).json({      success: false,      error: {        code: err.code || 'INTERNAL_ERROR',        message: err.message || 'An unexpected error occurred',      },    })  }}

6. Developer Overlay & Formatting Utilities

The module exports diagnostic utilities used for CLI logging, test assertions, and debugging:

Utility FunctionSignatureDescription
formatDevError(err: Error, options?: { routeFile?: string; title?: string }) => voidPrints terminal error frame with code snippet and line pointers.
renderDevErrorToString(err: Error, options?: { routeFile?: string; title?: string }) => stringReturns the formatted terminal error box as an ANSI string.
categorizeError(err: Error) => stringReturns a human-readable category (e.g. 'Validation Error').
generateErrorHint(err: Error) => string | nullProduces actionable remediation advice for recognized errors.
buildCodeFrame(filePath: string, line: number, col?: number) => stringConstructs visual code snippet frame around line and column coordinates.
stripInternalStackFrames(stack?: string) => string[]Filters out Node.js internal and framework runtime stack frames.
devErrorResponse(err: Error, routeFile?: string) => Record<string, any>Formats structured JSON error response for development clients.