0
0
NestJSframework~5 mins

Exception mapping interceptor in NestJS

Choose your learning style9 modes available
Introduction

An exception mapping interceptor helps catch errors in your NestJS app and change them into friendly responses.

You want to send custom error messages to users instead of default ones.
You need to log errors and still return a clean response.
You want to transform different error types into a standard format.
You want to handle errors globally in one place.
You want to add extra info to error responses like timestamps.
Syntax
NestJS
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable, catchError, throwError } from 'rxjs';

@Injectable()
export class ExceptionMappingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      catchError(error => {
        // Map or transform the error here
        const mappedError = new Error('Custom error message');
        return throwError(() => mappedError);
      }),
    );
  }
}

The interceptor uses RxJS catchError to catch errors from the request stream.

You must return an observable error using throwError(() => error) in RxJS 7+.

Examples
Simple error mapping to a new error with a custom message.
NestJS
catchError(error => {
  const mappedError = new Error('Something went wrong');
  return throwError(() => mappedError);
})
Maps only 404 errors to a custom message, passes others unchanged.
NestJS
catchError(error => {
  if (error.status === 404) {
    return throwError(() => new Error('Resource not found'));
  }
  return throwError(() => error);
})
Logs the original error and returns a generic error message.
NestJS
catchError(error => {
  console.error('Logging error:', error.message);
  return throwError(() => new Error('Internal server error'));
})
Sample Program

This interceptor catches any error thrown in the controller and changes it to a 400 Bad Request with a custom message.

When you call GET /test, instead of the original error, you get a clean custom error response.

NestJS
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, HttpException, HttpStatus } from '@nestjs/common';
import { Observable, catchError, throwError } from 'rxjs';

@Injectable()
export class ExceptionMappingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      catchError(error => {
        // Map any error to HttpException with status 400 and custom message
        const customError = new HttpException('Custom bad request error', HttpStatus.BAD_REQUEST);
        return throwError(() => customError);
      }),
    );
  }
}

// Usage example in a controller
import { Controller, Get, UseInterceptors } from '@nestjs/common';

@Controller('test')
@UseInterceptors(ExceptionMappingInterceptor)
export class TestController {
  @Get()
  getTest() {
    throw new Error('Original error');
  }
}
OutputSuccess
Important Notes

Interceptors run before and after the request handler, so they can catch errors thrown anywhere in the flow.

Always return a new error inside throwError(() => error) to keep RxJS happy.

You can use this pattern to unify error responses across your app.

Summary

An exception mapping interceptor catches errors and changes them to friendly responses.

Use RxJS catchError inside the interceptor to handle errors.

This helps keep your API responses consistent and user-friendly.