Open In App

Error Handling In NestJS

Last Updated : 24 Sep, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

NestJS is a progressive, Node.js framework for building efficient and scalable server-side applications. One of the key advantages of NestJS is its powerful dependency injection system and modular structure, which makes building enterprise-level applications more manageable.

In this article, we will explore how error handling works in NestJS and common strategies for managing exceptions

Understanding Error Handling in NestJS

Error handling in NestJS revolves around exceptions. In NestJS, errors are treated as exceptions, and the framework has a built-in exception-handling system to deal with these errors. When an error occurs, it is either thrown or caught within the system, and NestJS provides mechanisms to customize the way these exceptions are handled.

NestJS has a default error-handling mechanism that catches unhandled exceptions and sends appropriate responses, but it also allows developers to extend and customize the handling process based on the specific needs of the application.

Setting Up NestJS Application For Error Handling

Step 1: Ensure you have Node.js and npm installed

You can download and install from the site of the node.js

node --version
npm --version

Step 2: Install NestJS CLI

If you haven't already, install the NestJS CLI globally using npm:

npm install -g @nestjs/cli

Step 3: Create a new NestJS Project

If you don't have a project yet, create one using the CLI and add the project file to the terminal.

nest new my-nest-project
cd my-nest-project

Step 4: Run the application

Use the following command to start your NestJS application.

npm run start

Folder Structure

Screenshot-2024-09-14-142118
Folder Structure

Dependencies

"dependencies": {
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/platform-express": "^10.0.0",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1"
}

Various Approaches for Error Handling in NestJS

Approach 1: Built-in Exception Filters

NestJS gives integrated exception filters, like HttpException, which can help you throw commonplace HTTP errors consisting of 404, 400, 500, and etc.

Syntax:

throw new HttpException('Error Message', HttpStatus.BAD_REQUEST);

Example:

JavaScript
//my-nest-project\src\example.controller.ts

import { Controller, Get, HttpException, HttpStatus } from '@nestjs/common';

@Controller('example')
export class ExampleController {
    @Get()
    getExample() {
        throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
    }
}
JavaScript
//.\my-nest-project\src\app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ExampleController } from './example.controller';

@Module({
    imports: [],
    controllers: [AppController, ExampleController],
    providers: [AppService],
})
export class AppModule { }


Output:

Screenshot-2024-09-14-140832
Built-in Exception Filters

Approach 2: Custom Exception Filters

Custom exception filters assist you to manage exceptions in a custom way via extending the ExceptionFilter class and implementing the seize approach.

Example:

JavaScript
//.\nest2\src\cats\custom-exception.filter.ts

import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';

@Catch(HttpException)
export class CustomExceptionFilter implements ExceptionFilter {
    catch(exception: HttpException, host: ArgumentsHost) {
        const ctx = host.switchToHttp();
        const response = ctx.getResponse<Response>();
        const request = ctx.getRequest<Request>();
        const status = exception.getStatus();
        const message = exception.message;

        response
            .status(status)
            .json({
                statusCode: status,
                message: message,
                timestamp: new Date().toISOString(),
                path: request.url,
            });
    }
}
JavaScript
//.\nest2\src\cats\cats.controller.ts

import { Controller, Get, HttpException, HttpStatus, UseFilters } from '@nestjs/common';
import { CustomExceptionFilter } from './custom-exception.filter';

@Controller('cats')
@UseFilters(CustomExceptionFilter)
export class CatsController {
    @Get()
    findAll() {
        throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
    }
}


Output

Screenshot-2024-09-14-144629
Custom Exception Filters

Approach 3: Global Exception Filters

Global exception filters may be used to deal with exceptions throughout the entire software. You can installation a global exception filter by using the usage of the app.UseGlobalFilters() method.

Example:

JavaScript
// custom-exception.filter.ts

import { HttpException, ExceptionFilter, Catch, ArgumentsHost } from '@nestjs/common';

@Catch(HttpException)
export class GlobalExceptionFilter implements ExceptionFilter {
    catch(exception: HttpException, host: ArgumentsHost) {
        const ctx = host.switchToHttp();
        const response = ctx.getResponse();
        const status = exception.getStatus();

        response.status(status).json({
            statusCode: status,
            message: exception.message,
            timestamp: new Date().toISOString(),
        });
    }
}
JavaScript
//main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { GlobalExceptionFilter } from './global-exception.filter';

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    app.useGlobalFilters(new GlobalExceptionFilter());
    await app.listen(3000);
}
bootstrap();


Output:

Screenshot-2024-09-14-144618
Global Exception Filters

Approach 4: HttpException

HttpException is a integrated magnificence in NestJS for throwing HTTP-related errors.

Syntax:

throw new HttpException('Custom error message', HttpStatus.FORBIDDEN);

Example:

JavaScript
//.\src\example\example.controller.ts

import { Controller, Get, HttpException, HttpStatus } from '@nestjs/common';

@Controller('example')
export class ExampleController {
    @Get()
    findAll() {
        throw new HttpException(
            {
                statusCode: HttpStatus.FORBIDDEN,
                message: 'Forbidden resource',
            },
            HttpStatus.FORBIDDEN,
        );
    }
}


Output:

{
"statusCode": 403,
"message": "Forbidden resource"
}

Approach 5: Using Middleware for Error Handling

Middleware in NestJS also can be used for errors handling with the aid of catching exceptions and modifying the reaction.

Example:

JavaScript
//.\src\example.controller.ts

import { Controller, Get, HttpException, HttpStatus } from '@nestjs/common';

@Controller('example')
export class ExampleController {
    @Get()
    findAll() {
        throw new HttpException(
            {
                statusCode: HttpStatus.FORBIDDEN,
                message: 'Forbidden resource',
            },
            HttpStatus.FORBIDDEN,
        );
    }
}
JavaScript
//.\src\app.module.ts

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ExampleController } from './example.controller';
import { ErrorHandlingMiddleware } from './error-handling.middleware';

@Module({
    imports: [],
    controllers: [AppController, ExampleController],
    providers: [AppService],
})
export class AppModule implements NestModule {
    configure(consumer: MiddlewareConsumer) {
        consumer
            .apply(ErrorHandlingMiddleware)
            .forRoutes('*');
    }
}


Output

Screenshot-2024-09-14-155252
Using Middleware for Error Handling

Approach 6: Using Interceptors

Interceptors can trap mistakes and alter responses earlier than they may be despatched to the patron.

Example:

JavaScript
// main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ErrorInterceptor } from './error.interceptor';

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    app.useGlobalInterceptors(new ErrorInterceptor());
    await app.listen(3000);
}
bootstrap();
JavaScript
//error.interseptor.ts

import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorInterceptor implements NestInterceptor {
    intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        return next.handle().pipe(
            catchError((error) => {
                if (error instanceof HttpException) {
                    return throwError(() => 
                        new HttpException({ message: 'Error intercepted' }, error.getStatus()));
                }
                return throwError(() => 
                    new HttpException({ message: 'Error intercepted' }, 500));
            }),
        );
    }
}


Output:

Screenshot-2024-09-14-161314
Using Interceptors

Next Article

Similar Reads