typescript 58 lines · 8 steps

A catch-all exception filter in NestJS

One filter turns any thrown error into a consistent, structured JSON response.

Explained by highlit
1import {
2 ArgumentsHost,
3 Catch,
4 ExceptionFilter,
5 HttpException,
6 HttpStatus,
7 Logger,
8} from '@nestjs/common';
9import { HttpAdapterHost } from '@nestjs/core';
10import { Request } from 'express';
11 
12interface ErrorResponse {
13 statusCode: number;
14 message: string | string[];
15 error: string;
16 path: string;
17 timestamp: string;
18}
19 
20@Catch()
21export class AllExceptionsFilter implements ExceptionFilter {
22 private readonly logger = new Logger(AllExceptionsFilter.name);
23 
24 constructor(private readonly httpAdapterHost: HttpAdapterHost) {}
25 
26 catch(exception: unknown, host: ArgumentsHost): void {
27 const { httpAdapter } = this.httpAdapterHost;
28 const ctx = host.switchToHttp();
29 const request = ctx.getRequest<Request>();
30 
31 const isHttp = exception instanceof HttpException;
32 const statusCode = isHttp
33 ? exception.getStatus()
34 : HttpStatus.INTERNAL_SERVER_ERROR;
35 
36 const cause = isHttp ? exception.getResponse() : null;
37 const message =
38 typeof cause === 'object' && cause !== null && 'message' in cause
39 ? (cause as { message: string | string[] }).message
40 : isHttp
41 ? exception.message
42 : 'Internal server error';
43 
44 const body: ErrorResponse = {
45 statusCode,
46 message,
47 error: HttpStatus[statusCode] ?? 'Error',
48 path: request.url,
49 timestamp: new Date().toISOString(),
50 };
51 
52 if (statusCode >= HttpStatus.INTERNAL_SERVER_ERROR) {
53 this.logger.error(`${request.method} ${request.url}`, exception instanceof Error ? exception.stack : exception);
54 }
55 
56 httpAdapter.reply(ctx.getResponse(), body, statusCode);
57 }
58}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1A single @Catch() filter centralizes error formatting so every route returns the same shape.
  2. 2Using the HttpAdapterHost keeps the filter platform-agnostic instead of tied to Express directly.
  3. 3Distinguishing HttpException from unknown throws lets you preserve intended status codes while defaulting the rest to 500.

Related explainers

Share this explainer

Here's the card — post it anywhere.

A catch-all exception filter in NestJS — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code