Suggest an editImprove this articleRefine the answer for “What is an Exception Filter?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)An Exception Filter is a class that catches exceptions raised while a request is being processed and controls what response the client gets: it implements the `ExceptionFilter` interface with a `catch(exception, host)` method, and is marked with the `@Catch()` decorator that names the exception type to catch. **Key point:** Nest has a built-in filter for `HttpException` by default, but a custom filter (applied locally via `@UseFilters()` or globally via `app.useGlobalFilters()`) is what lets you uniformly format non-standard errors (e.g. from the database) into structured JSON.Shown above the full answer for quick recall.Answer (EN)Image## 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 ```javascript @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: ```javascript { "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 ```javascript 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): ```javascript @UseFilters(AllExceptionsFilter) @Controller('users') export class UsersController { @Get() findAll() { throw new Error('Something went wrong'); } } ``` ### 2. Globally (for the whole application): ```javascript 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**. ```javascript 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: ```javascript 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 1. A controller or service throws an exception. 2. Nest tries to find a matching Exception Filter. 3. If a filter is found → it processes the error and builds the response. 4. 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 ```javascript @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. |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.