What is an Exception Filter?
What an Exception Filter is
An Exception Filter is a class that catches errors (exceptions) raised while a request is being processed, and controls what response the client gets.
If a controller or service throws (
throw new Error()/throw new HttpException()), a filter can catch it, turn it into a readable response, and return structured JSON to the client.
An example without a filter
@Controller('users')
export class UsersController {
@Get(':id')
findOne(@Param('id') id: string) {
if (id !== '1') {
throw new NotFoundException('User not found');
}
return { id: 1, name: 'John' };
}
}By default, NestJS wraps standard exceptions (HttpException)
into a convenient response shape:
{
"statusCode": 404,
"message": "User not found",
"error": "Not Found"
}But if you throw a non-standard error (throw new Error('DB error')),
Nest doesn't know how to format it, and returns a 500 with no formatting.
That's where an Exception Filter comes in.
A custom Exception Filter example
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
HttpStatus,
} from '@nestjs/common';
@Catch() // catches EVERY error
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.getResponse()
: 'Internal server error';
response.status(status).json({
statusCode: status,
message,
path: request.url,
timestamp: new Date().toISOString(),
});
}
}Attaching an Exception Filter
1. Locally (on a controller or method):
@UseFilters(AllExceptionsFilter)
@Controller('users')
export class UsersController {
@Get()
findAll() {
throw new Error('Something went wrong');
}
}2. Globally (for the whole application):
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { AllExceptionsFilter } from './filters/all-exceptions.filter';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new AllExceptionsFilter());
await app.listen(3000);
}
bootstrap();Now any thrown exception gets caught by the filter, and the client gets a tidy, consistent response.
An example filter for a specific error type
You can catch only certain kinds of exceptions.
import { Catch, ExceptionFilter, ArgumentsHost, NotFoundException } from '@nestjs/common';
@Catch(NotFoundException)
export class NotFoundFilter implements ExceptionFilter {
catch(exception: NotFoundException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
response.status(404).json({
error: 'Resource not found',
details: exception.message,
});
}
}This filter only fires for throw new NotFoundException().
What ArgumentsHost does
ArgumentsHost is a universal object
that gives access to the execution context: HTTP, WebSocket, or RPC.
For an HTTP request:
const ctx = host.switchToHttp();
const request = ctx.getRequest();
const response = ctx.getResponse();Through it, you can access:
- the request (
request); - the response (
response); - the execution context (
context).
How filters work, step by step
- A controller or service throws an exception.
- Nest tries to find a matching Exception Filter.
- If a filter is found → it processes the error and builds the response.
- If not → Nest falls back to its built-in default filter.
Common uses
| Purpose | Example |
|---|---|
| A unified error format | The same JSON response shape for every exception |
| Handling business errors | "Insufficient permissions", "Account blocked" |
| Database errors | Catching SQL/Prisma errors and returning a friendly message |
| Different contexts | Filters can be written for WebSocket, GraphQL, RPC |
An example: a Prisma filter
@Catch(Prisma.PrismaClientKnownRequestError)
export class PrismaExceptionFilter implements ExceptionFilter {
catch(exception: Prisma.PrismaClientKnownRequestError, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
if (exception.code === 'P2002') {
response.status(409).json({
error: 'Conflict',
message: 'Duplicate entry',
});
} else {
response.status(500).json({
error: 'Database error',
message: exception.message,
});
}
}
}Summary
| Concept | Description |
|---|---|
| Exception Filter | A mechanism for catching and handling exceptions |
| Interface | ExceptionFilter with a catch(exception, host) method |
| Decorator | @Catch(), names the exception type |
| Applied via | @UseFilters() or app.useGlobalFilters() |
| Goal | Centralized error handling and response formatting |
| By default | Nest has a built-in filter for HttpException |
| Extensions | Custom filters can be written for the DB, auth, logging, etc. |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.