Global exception filters help catch and handle errors in one place for your whole NestJS app. This keeps your code clean and consistent.
Global exception filters in NestJS
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common'; import { Request, Response } from 'express'; @Catch() export class AllExceptionsFilter implements ExceptionFilter { catch(exception: unknown, host: ArgumentsHost) { const ctx = host.switchToHttp(); const response = ctx.getResponse<Response>(); const request = ctx.getRequest<Request>(); const status = exception instanceof HttpException ? exception.getStatus() : 500; response.status(status).json({ statusCode: status, timestamp: new Date().toISOString(), path: request.url, message: exception instanceof HttpException ? exception.getResponse() : 'Internal server error', }); } } // To apply globally in main.ts // app.useGlobalFilters(new AllExceptionsFilter());
The @Catch() decorator without arguments catches all exceptions.
Use app.useGlobalFilters() in your main bootstrap file to apply the filter globally.
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common'; @Catch(HttpException) export class HttpExceptionFilter implements ExceptionFilter { catch(exception: HttpException, host: ArgumentsHost) { // handle only HttpException errors } }
app.useGlobalFilters(new AllExceptionsFilter());
This example shows a global exception filter catching all errors. The '/error' route throws a known HTTP error, '/unknown-error' throws a normal error, and '/hello' returns a normal response. The filter sends JSON error responses for exceptions.
import { NestFactory } from '@nestjs/core'; import { Module, Controller, Get } from '@nestjs/common'; import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common'; import { Request, Response } from 'express'; @Catch() class AllExceptionsFilter implements ExceptionFilter { catch(exception: unknown, host: ArgumentsHost) { const ctx = host.switchToHttp(); const response = ctx.getResponse<Response>(); const request = ctx.getRequest<Request>(); const status = exception instanceof HttpException ? exception.getStatus() : 500; response.status(status).json({ statusCode: status, timestamp: new Date().toISOString(), path: request.url, message: exception instanceof HttpException ? exception.getResponse() : 'Internal server error', }); } } @Controller() class AppController { @Get('error') throwError() { throw new HttpException('Custom error message', 400); } @Get('unknown-error') throwUnknownError() { throw new Error('Unknown error'); } @Get('hello') hello() { return 'Hello World!'; } } @Module({ controllers: [AppController], }) class AppModule {} async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalFilters(new AllExceptionsFilter()); await app.listen(3000); } bootstrap();
Global filters catch exceptions from all controllers and services.
Always return consistent error response shapes for better client handling.
Use instanceof HttpException to check if the error is a known HTTP error.
Global exception filters catch errors app-wide in one place.
They help send consistent error responses and improve app stability.
Apply them in main.ts using app.useGlobalFilters().
Practice
Solution
Step 1: Understand the role of exception filters
Exception filters in NestJS are designed to catch errors and exceptions that occur during request processing.Step 2: Identify the scope of global exception filters
Global exception filters apply this error handling across the entire app, centralizing error management.Final Answer:
To catch and handle exceptions across the entire application in one place -> Option AQuick Check:
Global exception filters = app-wide error handling [OK]
- Confusing filters with routing or database management
- Thinking filters serve static files
- Assuming filters only handle specific routes
main.ts file of a NestJS app?Solution
Step 1: Recall the NestJS method for global filters
The official method to apply global exception filters isuseGlobalFilters()on the app instance.Step 2: Check the syntax for passing the filter
The filter must be instantiated withnewbefore passing it touseGlobalFilters().Final Answer:
app.useGlobalFilters(new MyExceptionFilter()) -> Option AQuick Check:
Global filter method = useGlobalFilters() [OK]
- Using incorrect method names like setGlobalFilters
- Passing class without instantiation
- Confusing with middleware registration methods
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
if (exception instanceof HttpException) {
const status = exception.getStatus();
response.status(status).json({ message: exception.message });
} else {
response.status(500).json({ message: 'Internal server error' });
}
}
}Solution
Step 1: Analyze the filter's catch method
The filter checks if the exception is an instance of HttpException and uses its status code.Step 2: Determine status code for other exceptions
If not an HttpException, it returns status 500 with a generic error message.Final Answer:
Depends on the exception type -> Option CQuick Check:
HttpException status or 500 for others [OK]
- Assuming always 500 status
- Ignoring HttpException status extraction
- Confusing 404 with 500 errors
import { ExceptionFilter, Catch, ArgumentsHost } from '@nestjs/common';
@Catch()
export class MyFilter implements ExceptionFilter {
catch(exception: any, host: ArgumentsHost) {
const response = host.getResponse();
response.status(400).json({ error: 'Bad Request' });
}
}Solution
Step 1: Check how to get response object
In NestJS, to get the HTTP response, usehost.switchToHttp().getResponse(), nothost.getResponse().Step 2: Verify other parts
The @Catch() decorator can be empty to catch all exceptions, and the catch method does not need to return a value. @Injectable() is not required for filters.Final Answer:
host.getResponse() is incorrect; should use host.switchToHttp().getResponse() -> Option DQuick Check:
Use switchToHttp() to access response [OK]
- Calling host.getResponse() directly
- Thinking @Injectable() is mandatory for filters
- Expecting catch to return a value
catch method?Solution
Step 1: Handle HttpException separately
Check if the exception is an instance of HttpException to preserve its status and message.Step 2: For other exceptions, log and respond with status 418
Log the error details, then send a JSON response with status 418 and a custom message.Final Answer:
Check if exception is HttpException, use its status; else log and respond with 418 and custom message -> Option BQuick Check:
Preserve HttpException status, else respond 418 with log [OK]
- Ignoring HttpException status and always sending 418
- Not logging exceptions
- Re-throwing exceptions instead of handling
Ready to prove it?
Pass the test and this pattern moves unknown
