0
0
NestjsHow-ToBeginner ยท 4 min read

How to Create Exception Filter in NestJS: Simple Guide

In NestJS, create an exception filter by implementing the ExceptionFilter interface and overriding the catch() method to handle errors. Use the @Catch() decorator to specify which exceptions to catch, then apply the filter globally or to specific controllers or routes.
๐Ÿ“

Syntax

An exception filter in NestJS is a class that implements the ExceptionFilter interface. It must have a catch(exception, host) method where you define how to handle the error.

The @Catch() decorator specifies which exceptions the filter handles. If empty, it catches all exceptions.

You can apply the filter globally, to controllers, or to individual routes.

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

@Catch(HttpException) // specify exception type or leave empty for all
export class MyExceptionFilter 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(),
    });
  }
}
๐Ÿ’ป

Example

This example shows a custom exception filter that catches all exceptions and returns a JSON response with status code, message, and timestamp. It is applied globally in the main app module.

typescript
import { ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

@Catch() // catches all exceptions
export class AllExceptionsFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();

    const status = exception instanceof HttpException
      ? exception.getStatus()
      : HttpStatus.INTERNAL_SERVER_ERROR;

    const message = exception instanceof HttpException
      ? exception.message
      : 'Internal server error';

    response.status(status).json({
      statusCode: status,
      timestamp: new Date().toISOString(),
      path: request.url,
      message,
    });
  }
}

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new AllExceptionsFilter());
  await app.listen(3000);
}
bootstrap();
Output
When an error occurs, the server responds with JSON like: { "statusCode": 404, "timestamp": "2024-06-01T12:00:00.000Z", "path": "/nonexistent", "message": "Not Found" }
โš ๏ธ

Common Pitfalls

  • Not implementing the ExceptionFilter interface correctly causes the filter not to work.
  • Forgetting to use the @Catch() decorator means the filter won't catch any exceptions.
  • Not calling host.switchToHttp() properly can cause errors when accessing response or request.
  • Applying the filter only locally when you want global error handling.
typescript
/* Wrong: Missing @Catch decorator */
export class WrongFilter implements ExceptionFilter {
  catch(exception: any, host: ArgumentsHost) {
    // This filter will never be triggered
  }
}

/* Right: With @Catch decorator */
import { Catch, ExceptionFilter, ArgumentsHost } from '@nestjs/common';

@Catch()
export class RightFilter implements ExceptionFilter {
  catch(exception: any, host: ArgumentsHost) {
    // This filter will catch all exceptions
  }
}
๐Ÿ“Š

Quick Reference

Use @Catch() to define which exceptions to catch.

Implement catch(exception, host) to handle the error.

Apply filters globally with app.useGlobalFilters(), or locally with @UseFilters() on controllers or routes.

ConceptDescriptionUsage
@Catch()Decorator to specify exception types to catch@Catch(HttpException) or @Catch() for all
ExceptionFilterInterface to implement for custom filtersclass MyFilter implements ExceptionFilter
catch()Method to handle exceptionscatch(exception, host) { ... }
useGlobalFilters()Apply filter globallyapp.useGlobalFilters(new MyFilter())
@UseFilters()Apply filter locally@UseFilters(MyFilter) on controller or route
โœ…

Key Takeaways

Create exception filters by implementing ExceptionFilter and using @Catch() decorator.
Use catch() method to customize error response handling.
Apply filters globally with app.useGlobalFilters() or locally with @UseFilters().
Always specify exception types in @Catch() or leave empty to catch all.
Avoid missing @Catch() decorator or incorrect method signatures to ensure filters work.