Creating and Using NestJS Exception Filters

Learn how to create and use exception filters in NestJS.

overview

NestJS allows you to customize how exceptions are handled using exception filters. Exception filters are called when an exception occurs and generate an appropriate response based on the content of the exception.

How to create an exception filter

To create an exception filter, first create a class that implements the ExceptionFilter interface. This interface has a catch method, which takes an exception and a host (objects with HTTP request and response information). Below is an example of creating your own exception filter.

Execute the following command to create an exception filter.

nest g f users/filters/http-exception

/src/common/filters/http-exception/http-exception.filter.ts

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

@Catch(HttpException)
export class HttpExceptionFilter 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,
      });
  }
}

The code above creates an exception filter named HttpExceptionFilter. This filter is called when an HttpException is thrown.

How to use exception filters

To use the created exception filters, use the @UseFilters decorator. By applying this decorator to a method or controller, you can filter exceptions that occur in that scope.

Below is an example of using the created exception filter.

/src/users/users.controller.ts

import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  HttpException,
  HttpStatus,
  Use filters,
} from '@nestjs/common';
import { UsersService } from './users.service';
import { ForbiddenException } from './exceptions/forbidden.exception';
import { HttpExceptionFilter } from './filters/http-exception.filter';


@Controller('users')
@UseFilters(new HttpExceptionFilter())
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Get()
  getUsers(): User[] {
    return this.usersService.getUsers();
  }

  @Post()
  addUser(@Body() name: string): void {
    this.usersService.addUser(name);
  }

  @Put(':id')
  putUser(@Param('id') id: number, @Body('name') name: string): void {
    this.usersService.putUser(id, name);
  }

  @Delete(':id')
  deleteUser(@Param('id') id: number): void {
    this.usersService.deleteUser(id);
  }
  @Get('throw')
  getException(): string {
    throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
  }
  @Get('custom_throw')
  getCustomException(): string {
    throw new ForbiddenException();
  }
}

The code above applies the HttpExceptionFilter throughout the UsersController. With this, any HttpException that occurs in this controller will be handled by HttpExceptionFilter.

test

$ curl http://localhost:3000/users/throw
## output
{"statusCode":403,"timestamp":"2021-07-11T14:41:39.000Z","path":"/users/throw"}

summary

NestJS allows you to customize how exceptions are handled using exception filters. Exception filters are called when an exception occurs and generate an appropriate response based on the content of the exception. This allows more flexibility in error handling.