Exception Filters
- NestJS
- Error Handling
- Node.js
A centralised mechanism that catches errors thrown anywhere in request handling and turns them into consistent, safe HTTP responses.
Prerequisites
- Error handling and middleware (see Related Topics)
What you'll understand
- What an exception filter does in a request pipeline
- How centralising error handling produces consistent responses
- How thrown exceptions map to HTTP status codes
Explanation
An exception filter is a dedicated place that catches errors thrown during request handling and converts them into a proper HTTP response. It is the framework-level expression of centralised error handling (see Related Topics): rather than each controller wrapping its logic in try/catch and formatting errors itself, code simply throws, and the filter decides how every error becomes a response.
The payoff is consistency and safety. Because one filter handles all errors, every failure comes back in the same shape and with the right status code, which pairs directly with a consistent response format (see Related Topics). It is also the single choke point for safety: the filter logs the full detail for you and returns a generic message for unexpected errors, so internal information and stack traces never leak to the client.
The mapping from error to response is the filter’s core job. Known, expected errors carry their own status, a not-found exception becomes 404, a validation error 400, an unauthorised one 401. Anything unrecognised is treated as an unexpected failure and returned as 500. In NestJS this is built in: throwing an HttpException sets the status, and a global exception filter catches everything for uniform handling.
Examples
This TypeScript example throws a typed HTTP exception; the framework maps it to the right status without a manual response:
import { NotFoundException } from '@nestjs/common';
async findUser(id: number) {
const user = await this.repo.findById(id);
if (!user) throw new NotFoundException('User not found'); // becomes 404
return user;
}A global exception filter catches everything, logs the detail, and returns a consistent body for unexpected errors:
@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
// log full detail, then send a safe, consistently shaped response
}
}Common mistakes
- Repeating try/catch and ad-hoc error formatting in every controller.
- Letting unexpected errors leak stack traces or internal messages to clients.
- Returning inconsistent error shapes from different parts of the app.
- Mapping every error to 500 instead of using accurate status codes.
Best practices
- Centralise error-to-response handling in one filter rather than per controller.
- Throw typed exceptions that carry the correct status code.
- Log full detail internally and return safe, generic messages for unexpected errors.
- Emit a consistent error shape that matches your response format (see Related Topics).
Further reading
- NestJS, Exception filters — https://docs.nestjs.com/exception-filters
- MDN, HTTP response status codes — https://developer.mozilla.org/en-US/docs/Web/HTTP/Status