JSPM

@webxsid/nest-exception

1.0.2
    • ESM via JSPM
    • ES Module Entrypoint
    • Export Map
    • Keywords
    • License
    • Repository URL
    • TypeScript Types
    • README
    • Created
    • Published
    • Downloads 6
    • Score
      100M100P100Q35071F
    • License MIT

    A centralized exception handling module for NestJS applications. It provides structured error management, logging, and automatic exception handling.

    Package Exports

    • @webxsid/nest-exception

    Readme

    @webxsid/nest-exception

    Coverage Test & Coverage NPM Version License

    A centralized exception handling module for NestJS applications. It provides structured error management, logging, and automatic exception handling.

    Features

    • Centralized Error Registry: Define and manage application errors easily.
    • Automatic Error Handling: Custom AppException class integrates seamlessly.
    • Flexible Error Registration: Predefine errors in the module or register dynamically.
    • Extendable Error Handling: Customize error handling with ExceptionFilter.
    • Stack Trace (Development Mode): Automatically captures stack trace for debugging.
    • Seamless Integration: Just import the module and start using it.

    Installation

    Install the package using npm or yarn:

    $ npm install @webxsid/nest-exception
    # or
    $ yarn add @webxsid/nest-exception

    Usage

    Importing and Setting Up the Module

    • Import the AppExceptionModule in the root module using forRoot or forRootAsync:
    import { Module } from '@nestjs/common';
    import { AppExceptionModule } from '@webxsid/nest-exception';
    
    @Module({
        imports: [AppExceptionModule.forRoot({
            isDev: process.env.NODE_ENV === 'development',
            errors: [
                { code: 'E001', message: 'User not found' },
                { code: 'E002', message: 'Invalid credentials' },
            ],
            logger: LoggerService // Any implementation of LoggerService
        })],
    })
    export class AppModule {}

    Async Configuration

    import { Module } from '@nestjs/common';
    import { AppExceptionModule } from '@webxsid/nest-exception';
    import { ConfigModule, ConfigService } from '@nestjs/config';
    
    @Module({
        imports: [
            ConfigModule.forRoot(),
            AppExceptionModule.forRootAsync({
                imports: [ConfigModule],
                useFactory: (configService: ConfigService) => ({
                    isDev: configService.get('NODE_ENV') === 'development',
                    errors: [
                        { code: 'E001', message: 'User not found' },
                        { code: 'E002', message: 'Invalid credentials' },
                    ],
                    logger: LoggerService // Any implementation of LoggerService
                }),
                inject: [ConfigService]
            })
        ],
    })
    export class AppModule {}

    Registering the Global Exception Filter

    To apply the AppExceptionFilter globally in your application, register it in your root module (AppModule):

    // app.module.ts
    import { Module } from '@nestjs/common';
    import { APP_FILTER } from '@nestjs/core';
    import { AppExceptionFilter } from '@webxsid/nest-exception';
    
    @Module({
        providers: [
            {
                provide: APP_FILTER,
                useClass: AppExceptionFilter,
            },
        ],
    })
    export class AppModule {}

    Error Management

    Registering Errors in the Module

    Errors can be pre-registered in the module configuration:

    imports: [
        AppExceptionModule.forRoot({
            errors: [
                { code: 'E001', message: 'User not found' },
                { code: 'E002', message: 'Invalid credentials' },
            ]
        })
    ]

    Registering Errors Dynamically

    • Use the ExceptionRegistry service to register errors at runtime:
    import { Injectable } from '@nestjs/common';
    import { ExceptionRegistry } from '@webxsid/nest-exception';
    
    @Injectable()
    export class AppService {
        constructor(private readonly exceptionRegistry: ExceptionRegistry) {}
    
        registerErrors() {
            this.exceptionRegistry.registerError({ code: 'E003', message: 'Invalid request' });
        }
    }

    Extending the Exception Handler

    • Use the ExceptionHandlerService to customize error handling for specific exceptions:
    import { Injectable, OnModuleInit } from '@nestjs/common';
    import { ExceptionHandlerService } from '@webxsid/nest-exception';
    import { ArgumentsHost, HttpStatus } from '@nestjs/common';
    
    @Injectable()
    export class MongoErrorHandler implements OnModuleInit {
        constructor(private readonly exceptionHandlerService: ExceptionHandlerService) {}
    
        onModuleInit() {
            this.exceptionHandlerService.register(MongoError, (exception: MongoError, host: ArgumentsHost) => {
                const response = host.switchToHttp().getResponse();
                response.status(HttpStatus.BAD_REQUEST).json({
                    statusCode: HttpStatus.BAD_REQUEST,
                    errorCode: 'MONGO_ERROR',
                    message: exception.message,
                    timestamp: new Date().toISOString(),
                });
            });
        }
    }
    • Add the handler class to the module providers:
    @Module({
        imports: [AppExceptionModule.forRoot(/*...*/)],
        providers: [MongoErrorHandler]
    })
    export class AppModule {}

    Throwing Custom Exceptions

    • Use the AppException class to throw predefined errors:
    import { Injectable } from '@nestjs/common';
    import { AppException } from '@webxsid/nest-exception';
    
    @Injectable()
    export class AppService {
        async getUser(id: string) {
            const user = await this.userService.findById(id);
            if (!user) {
                throw new AppException('E001');
            }
            return user;
        }
    }

    How It Works

    The AppException class simplifies error handling by checking if the provided error code exists in the Exception Registry. Here’s how it behaves in different scenarios:

    1. ✅ Passing a Registered Error Code

    If the error code exists in the registry (either pre-registered in the module or added dynamically), AppException will: • Retrieve the corresponding error message and status code. • Construct a structured HTTP response with the correct status, message, and code.

    throw new AppException('E001'); 

    Output:

    {
        "statusCode": 400,
        "errorCode": "E001",
        "message": "User not found",
        "timestamp": "2021-09-01T12:00:00.000Z"
    }

    (Assuming the error code 'E001' is registered with the message 'User not found' and status code 400)

    2. ❌ Passing an Unregistered Error Code or String

    If the error code is not found in the registry, AppException will: • Throw an internal server error with the default message and status code. • Log the error using the provided logger service.

    throw new AppException('Something went wrong'); 

    Output:

    {
        "statusCode": 500,
        "errorCode": "UNKNOWN_ERROR",
        "message": "Internal server error",
        "timestamp": "2021-09-01T12:00:00.000Z"
    }

    🛠️ Development Mode (Stack Trace)

    If development mode (isDev: true) is enabled, AppException will also include a stack trace for easier debugging:

    {
        "statusCode": 500,
        "errorCode": "UNKNOWN_ERROR",
        "message": "Internal server error",
        "timestamp": "2021-09-01T12:00:00.000Z",
        "stack": "Error: Internal server error\n    at AppService.getUser (/app/app.service.ts:12:13)\n    at processTicksAndRejections (internal/process/task_queues.js:93:5)"
    }

    License

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

    Acknowledgements

    Author

    Siddharth Mittal