NestJS comes with a built-in exceptions layer that handles all unhandled exceptions across the application. This layer ensures that when an exception is not handled by your application code, it is caught and processed, automatically sending a user-friendly response.
In this article, we’ll explore the built-in exception filters, how to use and customize them, and how to create your own exception filters.
What Are Exception Filters?
Exception filters in NestJS are a mechanism that lets you handle errors in a structured way across your application. They provide a centralized point to manage exceptions, log errors, and send appropriate responses back to the client.
In NestJS, exception filters are implemented using the ExceptionFilter interface. Filters can be applied:
- Globally: To handle exceptions across the entire application.
- At the Controller Level: To handle exceptions within a specific controller.
- At the Method Level: To handle exceptions for individual methods.
NestJS provides several ways to create and use exception filters:
1. Built-in HTTP Exception Filters
NestJS has integrated HTTP exception filters that the developer can use out of the box. These filters are supposed to work with HTTP-related exceptions to turn them over to the characteristic HTTP response.
Syntax:
import { Controller, Get, HttpException, HttpStatus } from '@nestjs/common';
@Controller('example')
export class ExampleController {
@Get()
getExample() {
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
}
Here for instance, should getExample() be called, NestJS raises an HttpException with status 403 Forbidden. This is done by the built-in exception filter which comes with major programming languages and simply sends back a standard message.
2. Custom Exception Filters
Creating custom exceptions allows for more flexibility and organization in your error handling. Custom exceptions can inherit from HttpException.
Syntax:
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class CustomHttpExceptionFilter 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();
response
.status(status)
.json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
});
}
}
In this example, the CustomHttpExceptionFilter handles HttpException and returns a custom JSON response.
3. Global Exception Filters
Global exception filters are quite different from other filters because they can be applied to each route handler as well as each controller in the application. They are particularly useful where there are exceptions that may occur in the course of the application.
Syntax:
import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';
import { CustomHttpExceptionFilter } from './filters/custom-http-exception.filter';
@Module({
providers: [
{
provide: APP_FILTER,
useClass: CustomHttpExceptionFilter,
},
],
})
export class AppModule { }
In this example, the CustomHttpExceptionFilter is registered as a global filter using the APP_FILTER token.
4. Method-Level Exception Filters
Method-level exception filters are applied to individual methods within a controller. This allows for fine-grained control over exception handling.
Syntax:
import { Controller, Get, UseFilters } from '@nestjs/common';
import { CustomHttpExceptionFilter } from './filters/custom-http-exception.filter';
@Controller('example')
export class ExampleController {
@Get()
@UseFilters(CustomHttpExceptionFilter)
getExample() {
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
}
In this example, the CustomHttpExceptionFilter is applied only to the getExample() method.
Binding Exception Filterswith Different Scopes
1. Global
Global filters handle exceptions across the entire application.
Syntax:
import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';
import { CustomExceptionFilter } from './filters/custom-exception.filter';
@Module({
providers: [
{
provide: APP_FILTER,
useClass: CustomExceptionFilter,
},
],
})
export class AppModule { }
2. Controller
Controller-level filters handle exceptions within a specific controller.
Syntax:
import { Controller, UseFilters, Get } from '@nestjs/common';
import { CustomExceptionFilter } from './filters/custom-exception.filter';
@UseFilters(CustomExceptionFilter)
@Controller('example')
export class ExampleController {
@Get()
getExample() {
throw new Error('Custom Error');
}
}
3. Method
Method-level filters handle exceptions for specific methods.
Syntax:
import { Controller, Get, UseFilters } from '@nestjs/common';
import { CustomExceptionFilter } from './filters/custom-exception.filter';
@Controller('example')
export class ExampleController {
@Get()
@UseFilters(CustomExceptionFilter)
getExample() {
throw new Error('Custom Error');
}
}
Steps To Implement Exception Filters in NestJS
Step 1: Install NestJS CLI
If you don't have the NestJS CLI installed, you can install it globally:
npm install -g @nestjs/cli
Step 2: Create a New NestJS Application
Create a new application using the NestJS CLI:
nest new exception-filter-demo
Navigate into the project directory:
cd exception-filter-demo
Folder Structure
NestJS Folder StructureDependencies
"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"
},
"devDependencies": {
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@types/express": "^4.17.17",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.1",
"@types/supertest": "^6.0.0",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"eslint": "^8.42.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"jest": "^29.5.0",
"prettier": "^3.0.0",
"source-map-support": "^0.5.21",
"supertest": "^7.0.0",
"ts-jest": "^29.1.0",
"ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3"
}
Step 3: Create a file named custom-http-exception.filter.ts:
JavaScript
//src/filters/custom-http-exception.filter.ts
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class CustomHttpExceptionFilter 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();
response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: exception.message,
});
}
}
Step 4: Apply the Filter Globally
Modify the app.module.ts to include the global filter:
JavaScript
//app.module.ts
import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CustomHttpExceptionFilter } from './filters/custom-http-exception.filter';
@Module({
imports: [],
controllers: [AppController],
providers: [
AppService,
{
provide: APP_FILTER,
useClass: CustomHttpExceptionFilter,
},
],
})
export class AppModule { }
Step 5: Create a Controller
Modify the app.controller.ts to include a route that throws an exception:
JavaScript
//app.controller.ts
import { Controller, Get, HttpException, HttpStatus } from '@nestjs/common';
@Controller()
export class AppController {
@Get()
getHello(): string {
throw new HttpException('This is a custom error', HttpStatus.BAD_REQUEST);
}
}
To start the application run the following command.
npm start
Output
When you run the application and navigate to the root URL, the custom exception filter will intercept the exception and return a structured JSON response:
Exception Filters in NestJSThis output demonstrates how the custom exception filter handles exceptions and formats the response according to the application's needs.
Similar Reads
Exception Handling in Distributed Systems Exception handling in distributed systems is crucial for maintaining reliability and resilience. This article explores strategies for managing errors across networked services, addressing challenges like fault tolerance, error detection, and recovery, to ensure seamless and robust system operation.I
11 min read
Define Exception handling in ES6 Exception: Exceptions are unwanted event that basically interrupts the normal flow of program. There are two types of exception in general:- Synchronous (eg. runtime errors)Asynchronous (eg. system errors) Exception Handling: Often a times exception happens in a program that causes the program to te
3 min read
Exception Handling in Node.js Exception handling refers to the mechanism by which the exceptions occurring in a code while an application is running is handled. Node.js supports several mechanisms for propagating and handling errors. There are different methods that can be used for exception handling in Node.js: Exception handl
3 min read
How to do exception handling in Ajax ? The purpose of this article is to demonstrate how we handle the exception in the jQuery AJAX request. A basic understanding of HTML, CSS, and jQuery is required. This can be done by an AJAX fail() method. We discuss 3 AJAX methods to better understand what's going on when making any ajax() request f
3 min read
Error Handling In NestJS 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
5 min read
Error Handling in ElectronJS ElectronJS is an Open Source Framework used for building Cross-Platform native desktop applications using web technologies such as HTML, CSS, and JavaScript which are capable of running on Windows, macOS, and Linux operating systems. It combines the Chromium engine and NodeJS into a Single Runtime.
7 min read