JSPM

  • Created
  • Published
  • Downloads 1226
  • Score
    100M100P100Q116119F
  • License MIT

A comprehensive TypeScript exception library with HTTP status code support, detailed JSDoc documentation, and backward compatibility. Provides structured error handling for web applications and APIs.

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (jsm-exceptions) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    JSM Exceptions

    npm version License: MIT

    A comprehensive TypeScript exception library with HTTP status code support, detailed JSDoc documentation, and backward compatibility. Provides structured error handling for web applications and APIs.

    ✨ Features

    • 🎯 HTTP Status Code Alignment: Each exception corresponds to appropriate HTTP status codes
    • 📝 Comprehensive JSDoc: Detailed documentation with examples for every exception
    • 🔄 Backward Compatibility: Maintains compatibility with existing code using @deprecated annotations
    • 🏗️ TypeScript Support: Full TypeScript support with proper type definitions
    • 🧩 Modular Design: Import only what you need
    • 🔍 Rich Context: Support for additional context and metadata in exceptions
    • Timestamps: Automatic timestamp tracking for debugging
    • 🎨 Validation Support: Built-in support for Joi validation errors

    📦 Installation

    npm install jsm-exceptions

    🚀 Quick Start

    Basic Usage

    import { BadRequestException, ValidationException, ItemNotFoundException } from 'jsm-exceptions';
    
    // Simple usage
    throw new BadRequestException('Invalid request format');
    
    // With additional context
    throw new ItemNotFoundException('User not found', { userId: '12345' });
    
    // Validation with field errors
    throw new ValidationException('Validation failed', {
      email: { value: 'invalid-email', message: 'Email format is invalid' },
      age: { value: -1, message: 'Age must be positive' }
    });

    Using the Base Exception

    import { BaseException } from 'jsm-exceptions';
    
    // Custom exception extending BaseException
    class CustomBusinessException extends BaseException {
      constructor(message: string, context?: Record<string, any>) {
        super(message, 422, context); // HTTP 422 Unprocessable Entity
      }
    }
    
    throw new CustomBusinessException('Business rule violation', {
      rule: 'maximum-orders-per-day',
      limit: 10,
      current: 11
    });

    📚 Available Exceptions

    4xx Client Errors

    Exception HTTP Code Description
    BadRequestException 400 Malformed or invalid requests
    UnauthorizedException 401 Authentication required or invalid
    InvalidPasswordException 401 Password authentication failures
    JWTTokenExpiredException 401 Expired JWT tokens
    ForbiddenException 403 Insufficient permissions
    ItemNotFoundException 404 Resource not found
    NoItemsFoundException 404 Search returned no results
    MethodNotAllowedException 405 HTTP method not supported
    RequestTimeoutException 408 Request timeouts
    ValueAlreadyExistsException 409 Resource conflicts
    ValidationException 422 Input validation failures
    UnprocessableEntityException 422 Semantic errors
    TooManyRequestsException 429 Rate limiting

    5xx Server Errors

    Exception HTTP Code Description
    InternalServerErrorException 500 Unexpected server errors
    NotImplementedException 501 Unimplemented features
    ServiceUnavailableException 503 Temporary service unavailability

    Special Cases

    Exception HTTP Code Description
    NoContentException 204 Valid request with no response body

    🔧 Advanced Usage

    Validation with Joi

    import Joi from 'joi';
    import { ValidationException } from 'jsm-exceptions';
    
    const schema = Joi.object({
      email: Joi.string().email().required(),
      age: Joi.number().min(0).required()
    });
    
    try {
      const { error } = schema.validate(data);
      if (error) {
        throw new ValidationException('Validation failed', error);
      }
    } catch (joiError) {
      // ValidationException automatically handles Joi.ValidationError
      throw new ValidationException('Input validation failed', joiError);
    }

    Error Handling in Express.js

    import express from 'express';
    import { BaseException, InternalServerErrorException } from 'jsm-exceptions';
    
    const app = express();
    
    // Error handling middleware
    app.use((error: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {
      if (error instanceof BaseException) {
        return res.status(error.status).json({
          success: false,
          error: {
            name: error.name,
            message: error.message,
            context: error.context,
            timestamp: error.timestamp
          }
        });
      }
      
      // Handle unexpected errors
      const internalError = new InternalServerErrorException('Unexpected error occurred');
      res.status(500).json({
        success: false,
        error: internalError.toJSON()
      });
    });

    Rate Limiting Example

    import { TooManyRequestsException } from 'jsm-exceptions';
    
    class RateLimiter {
      checkLimit(userId: string, limit: number, windowMs: number) {
        const requests = this.getUserRequests(userId, windowMs);
        
        if (requests.length >= limit) {
          throw new TooManyRequestsException('Rate limit exceeded', {
            userId,
            limit,
            windowMs,
            requestCount: requests.length,
            retryAfter: this.getRetryAfter(requests[0], windowMs)
          });
        }
      }
    }

    🔄 Migration from v1.x

    The library maintains backward compatibility, but we recommend migrating to the new exception names:

    // ❌ Old (deprecated)
    import { JsmException, InternalServerError, JWTTokenExpired } from 'jsm-exceptions';
    
    // ✅ New (recommended)
    import { BaseException, InternalServerErrorException, JWTTokenExpiredException } from 'jsm-exceptions';

    Deprecated exports will show warnings in TypeScript and include @deprecated JSDoc annotations.

    🎛️ Exception Properties

    All exceptions extend BaseException and include:

    interface ExceptionProperties {
      name: string;              // Exception class name
      message: string;           // Error message
      status: number;            // HTTP status code
      context?: Record<string, any>; // Additional context
      timestamp: Date;           // When the exception was created
      stack?: string;            // Stack trace
    }

    JSON Serialization

    const exception = new BadRequestException('Invalid input', { field: 'email' });
    
    console.log(exception.toJSON());
    // Output:
    // {
    //   name: 'BadRequestException',
    //   message: 'Invalid input',
    //   status: 400,
    //   context: { field: 'email' },
    //   timestamp: '2025-07-22T10:30:00.000Z',
    //   stack: '...'
    // }

    📋 API Reference

    BaseException

    The foundation class for all exceptions.

    class BaseException extends Error {
      constructor(message?: string, status?: number, context?: Record<string, any>)
      toJSON(): object
      toString(): string
    }

    ValidationException

    Special handling for validation errors with field-specific information.

    class ValidationException extends BaseException {
      fields: ErrorFields;
      isJoi: boolean;
      isMongoose: boolean;
      isCelebrate: boolean;
    }

    🤝 Contributing

    Contributions are welcome! Please read our contributing guidelines and submit pull requests for any improvements.

    📄 License

    This project is licensed under the MIT License - see the LICENSE file for details.