typescript 45 lines · 6 steps

Catch-all routes and error shaping in NestJS

A wildcard controller turns unmatched routes into 404s, and an exception filter renders every HttpException as consistent JSON.

Explained by highlit
1import {
2 Controller,
3 All,
4 Req,
5 NotFoundException,
6 HttpException,
7 ExceptionFilter,
8 Catch,
9 ArgumentsHost,
10 HttpStatus,
11} from '@nestjs/common';
12import { Request, Response } from 'express';
13 
14@Controller('*')
15export class NotFoundController {
16 @All()
17 handleUnknownRoute(@Req() req: Request): never {
18 throw new NotFoundException(
19 `Cannot ${req.method} ${req.originalUrl}`,
20 );
21 }
22}
23 
24@Catch(HttpException)
25export class HttpExceptionFilter implements ExceptionFilter {
26 catch(exception: HttpException, host: ArgumentsHost) {
27 const ctx = host.switchToHttp();
28 const res = ctx.getResponse<Response>();
29 const req = ctx.getRequest<Request>();
30 const status = exception.getStatus();
31 const payload = exception.getResponse();
32 
33 res.status(status).json({
34 statusCode: status,
35 error: HttpStatus[status] ?? 'Error',
36 message:
37 typeof payload === 'string'
38 ? payload
39 : (payload as { message?: string | string[] }).message ??
40 exception.message,
41 path: req.originalUrl,
42 timestamp: new Date().toISOString(),
43 });
44 }
45}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1A wildcard @Controller('*') gives you a single place to reject every route your app doesn't explicitly handle.
  2. 2An ExceptionFilter lets you intercept thrown exceptions and control the exact response body clients receive.
  3. 3Normalizing error payloads to a fixed shape makes APIs predictable for the clients that consume them.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Catch-all routes and error shaping in NestJS — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code