npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@thalorlabs/errors

v1.0.0

Published

Enhanced exception handling system for TypeScript applications with comprehensive error classes and debugging capabilities

Readme

@thalorlabs/errors

A comprehensive, production-ready exception handling system for TypeScript applications with enhanced features for debugging, monitoring, and API responses.

Installation

npm install @thalorlabs/errors

Features

  • Base CustomError class with enhanced context and debugging capabilities
  • HTTP-specific error classes for common API scenarios
  • Specialized error classes for validation, rate limiting, and database operations
  • Comprehensive test coverage (100% for all exception classes)
  • TypeScript support with full type safety
  • Structured error responses for consistent API responses
  • Request tracking with requestId and context support
  • Timestamp tracking for debugging and monitoring

Quick Start

import {
  // Base error class
  CustomError,

  // 4xx Client Errors
  BadRequestError,
  UnauthorizedError,
  ForbiddenError,
  NotFoundError,
  ConflictError,
  UnprocessableEntityError,
  TooManyRequestsError,

  // 5xx Server Errors
  InternalServerError,
  NotImplementedError,
  ServiceUnavailableError,
  GatewayTimeoutError,

  // Specialized error classes
  ValidationError, // Alias for UnprocessableEntityError (422)
  RateLimitError,
  DatabaseError,
  AuthenticationError, // Legacy alias for UnauthorizedError

  // Optional/Nice-to-have errors
  AuthenticationTimeoutError,
  ThirdPartyServiceError,
  PaymentRequiredError,
  QuotaExceededError,
} from '@thalorlabs/errors';

// Basic usage
throw new BadRequestError('Invalid input data');
throw new UnauthorizedError('Invalid API key');
throw new ForbiddenError('Insufficient permissions');

// With context and request tracking
throw new ValidationError(
  'Validation failed',
  [{ field: 'email', message: 'Invalid email format' }],
  'req-123',
  { userId: 'user-456' }
);

// Rate limiting with retry information
throw new TooManyRequestsError('Rate limit exceeded', 60, 100, 0, new Date());

// Database errors with detailed context
throw new DatabaseError(
  'Connection failed',
  'MongoDB',
  'find',
  DatabaseErrorType.CONNECTION_FAILED,
  originalError,
  'req-123',
  { collection: 'users' }
);

Error Classes

CustomError (Base Class)

The foundation for all custom errors with enhanced debugging capabilities.

class CustomError extends Error {
  statusCode: number;
  status: 'success' | 'failure';
  timestamp: Date;
  requestId?: string;
  context?: Record<string, any>;
}

Methods:

  • getStatusText(): Returns human-readable status text
  • toJSON(): Complete JSON representation for logging
  • getErrorResponse(): API-friendly response format

HTTP Error Classes

4xx Client Errors

BadRequestError (400)
throw new BadRequestError('Malformed input data', 'invalid-json', 'req-123');
UnauthorizedError (401)
throw new UnauthorizedError('Invalid API key', 'expired-token', 'req-123');
ForbiddenError (403)
throw new ForbiddenError(
  'Insufficient permissions',
  'admin-required',
  'req-123'
);
NotFoundError (404)
throw new NotFoundError('User not found', 'user-id-123', 'req-123');
ConflictError (409)
throw new ConflictError(
  'Resource already exists',
  'duplicate-email',
  'req-123'
);
UnprocessableEntityError (422)
throw new UnprocessableEntityError(
  'Semantically invalid request',
  'validation-failed',
  'req-123'
);
TooManyRequestsError (429)
throw new TooManyRequestsError(
  'Rate limit exceeded',
  60, // retryAfter seconds
  100, // limit
  0, // remaining
  new Date('2024-01-01T13:00:00Z'), // resetTime
  'req-123'
);

5xx Server Errors

InternalServerError (500)
throw new InternalServerError(
  'Unexpected server error',
  'database-connection-failed',
  'req-123'
);
NotImplementedError (501)
throw new NotImplementedError(
  'Endpoint not yet implemented',
  'v2-api-missing',
  'req-123'
);
ServiceUnavailableError (503)
throw new ServiceUnavailableError(
  'External service down',
  'weather-api',
  'req-123'
);
GatewayTimeoutError (504)
throw new GatewayTimeoutError(
  'Upstream service timeout',
  'database-query-timeout',
  'req-123'
);

Specialized Error Classes

ValidationError (422)

For input validation errors with detailed field-level information.

const validationError = new ValidationError(
  'Validation failed',
  [
    { field: 'email', message: 'Invalid email format', value: 'invalid-email' },
    { field: 'password', message: 'Password too short', value: '123' },
  ],
  'req-123'
);

// Add more validation errors dynamically
validationError.addValidationError('age', 'Must be 18 or older', 16, 'MIN_AGE');

throw validationError;

Response Format:

{
  "status": "failure",
  "error": "Validation failed",
  "timestamp": "2024-01-01T12:00:00.000Z",
  "requestId": "req-123",
  "errors": [
    {
      "field": "email",
      "message": "Invalid email format",
      "value": "invalid-email"
    }
  ]
}

RateLimitError (429)

For rate limiting scenarios with retry information.

throw new RateLimitError(
  'Rate limit exceeded',
  60, // retryAfter seconds
  100, // limit
  0, // remaining
  new Date('2024-01-01T13:00:00Z'), // resetTime
  'req-123'
);

Response Format:

{
  "status": "failure",
  "error": "Rate limit exceeded",
  "timestamp": "2024-01-01T12:00:00.000Z",
  "requestId": "req-123",
  "retryAfter": 60,
  "limit": 100,
  "remaining": 0,
  "resetTime": "2024-01-01T13:00:00.000Z"
}

DatabaseError (500)

For database-related errors with detailed context.

throw new DatabaseError(
  'Connection timeout',
  'MongoDB',
  'find',
  DatabaseErrorType.CONNECTION_FAILED,
  originalError,
  'req-123',
  { collection: 'users', query: { _id: '123' } }
);

DatabaseErrorType enum:

  • CONNECTION_FAILED
  • QUERY_FAILED
  • TRANSACTION_FAILED
  • CONSTRAINT_VIOLATION
  • TIMEOUT
  • DEADLOCK
  • UNKNOWN

Optional/Nice-to-have Error Classes

AuthenticationTimeoutError (440)

For authentication timeout scenarios (custom status code).

throw new AuthenticationTimeoutError(
  'Login session expired',
  'jwt-expired',
  'req-123'
);

ThirdPartyServiceError (502/503)

For external service failures with detailed context.

throw new ThirdPartyServiceError(
  'Payment gateway failed',
  'stripe-api',
  originalError,
  'req-123',
  { endpoint: '/process-payment' }
);

PaymentRequiredError (402)

For payment/subscription required scenarios.

throw new PaymentRequiredError(
  'Premium feature requires payment',
  'subscription-required',
  'req-123'
);

QuotaExceededError (429)

For quota/usage limit scenarios with detailed information.

throw new QuotaExceededError(
  'Monthly API quota exceeded',
  'api-calls',
  1000, // current usage
  1000, // max quota
  new Date('2024-02-01T00:00:00Z'), // reset time
  'req-123'
);

Integration with Middleware

The exception system integrates seamlessly with your existing TryCatchMiddleware:

// In TryCatchMiddleware.ts
if (error instanceof CustomError) {
  res.status(error.statusCode).json(error.getErrorResponse());
}

Best Practices

1. Use Specific Error Types

// Good
throw new ValidationError('Invalid input', validationErrors);

// Avoid
throw new CustomError(422, 'Invalid input');

2. Include Context for Debugging

throw new DatabaseError(
  'Query failed',
  'PostgreSQL',
  'SELECT',
  DatabaseErrorType.QUERY_FAILED,
  originalError,
  requestId,
  { table: 'users', query: 'SELECT * FROM users WHERE id = ?' }
);

3. Use Request IDs for Tracing

// Extract request ID from request headers or generate one
const requestId = req.headers['x-request-id'] || generateRequestId();

throw new BadRequestError('Invalid data', 'field-name', requestId);

4. Structured Error Responses

// For API responses
const response = error.getErrorResponse();

// For logging
const logData = error.toJSON();
logger.error('Error occurred', logData);

Testing

All error classes have comprehensive test coverage:

npm test
npm run test:coverage

Test Coverage:

  • ✅ 100% statement coverage
  • ✅ 97.36% branch coverage
  • ✅ 100% function coverage
  • ✅ 100% line coverage

Migration from Basic Errors

If you're upgrading from the basic error system:

// Before
throw new BadRequestError('Invalid input', 'field-name');

// After (backward compatible)
throw new BadRequestError('Invalid input', 'field-name');

// Enhanced (recommended)
throw new BadRequestError('Invalid input', 'field-name', requestId, {
  field: 'email',
});

Type Safety

The system is fully typed with TypeScript:

// All error classes extend CustomError
const error: CustomError = new ValidationError('Test');

// Type-safe error handling
if (error instanceof ValidationError) {
  // TypeScript knows this is a ValidationError
  console.log(error.validationErrors);
}

Performance Considerations

  • Minimal overhead: Base error class adds only essential properties
  • Optional context: Context and requestId are optional to avoid unnecessary memory usage
  • Efficient serialization: toJSON() and getErrorResponse() methods for different use cases
  • Stack trace preservation: Full Error inheritance maintains stack traces

Future Enhancements

The system is designed to be extensible:

  • Add new specialized error types as needed
  • Extend context with additional metadata
  • Add error correlation IDs for distributed systems
  • Implement error aggregation and reporting
  • Add error recovery suggestions

Project Structure

src/
├── index.ts                    # Main exports
├── CustomError.ts              # Base error class
├── AuthenticationError.ts      # Legacy alias for UnauthorizedError
├── AuthenticationTimeoutError.ts
├── ConflictError.ts            # 4xx Client Errors
├── ForbiddenError.ts
├── NotFoundError.ts
├── TooManyRequestsError.ts
├── UnauthorizedError.ts
├── UnprocessableEntityError.ts
├── GatewayTimeoutError.ts      # 5xx Server Errors
├── InternalServerError.ts
├── NotImplementedError.ts
├── ServiceUnavailableError.ts
├── DatabaseError.ts            # Specialized error classes
├── RateLimitError.ts
├── ValidationError.ts
├── ThirdPartyServiceError.ts   # Optional error classes
├── PaymentRequiredError.ts
├── QuotaExceededError.ts
└── tests/                      # Comprehensive test suite
    ├── CustomError.test.ts
    ├── AuthenticationError.test.ts
    └── ... (all error classes)

TypeScript Support

This package includes full TypeScript support with:

  • Complete type definitions
  • IntelliSense support
  • Compile-time type checking
  • Type-safe error handling

License

ISC

This enhanced exception system provides a solid foundation for robust error handling in production TypeScript applications.