Bird
Raised Fist0
NestJSframework~30 mins

Exception mapping interceptor in NestJS - Mini Project: Build & Apply

Choose your learning style10 modes available
Exception Mapping Interceptor in NestJS
📖 Scenario: You are building a NestJS backend API that needs to handle errors gracefully. Instead of sending raw error messages to clients, you want to map exceptions to friendly HTTP responses.
🎯 Goal: Create a NestJS interceptor called ExceptionMappingInterceptor that catches exceptions thrown by route handlers and maps them to custom error responses.
📋 What You'll Learn
Create an interceptor class named ExceptionMappingInterceptor implementing NestInterceptor.
Use RxJS catchError operator to catch exceptions.
Map exceptions to a custom error object with statusCode and message.
Throw an HttpException with the mapped error.
Apply the interceptor to a sample controller method.
💡 Why This Matters
🌍 Real World
Backend APIs often need to handle errors gracefully and send clear messages to clients. This interceptor helps centralize error handling.
💼 Career
Understanding interceptors and error handling in NestJS is essential for backend developers building robust and maintainable APIs.
Progress0 / 4 steps
1
Create the ExceptionMappingInterceptor class
Create a class called ExceptionMappingInterceptor that implements NestInterceptor. Import Injectable from @nestjs/common. Add the @Injectable() decorator above the class.
NestJS
Hint

Remember to import Injectable, NestInterceptor, ExecutionContext, and CallHandler from @nestjs/common.

2
Add RxJS catchError to intercept method
Inside the intercept method, return next.handle() piped with catchError from rxjs/operators. Import catchError from rxjs/operators and throwError from rxjs.
NestJS
Hint

Use next.handle().pipe(catchError(...)) to catch errors from the route handler.

3
Map exceptions to custom error and throw HttpException
Inside the catchError callback, create a variable mappedError with statusCode set to 500 and message set to 'Internal server error'. Import HttpException from @nestjs/common. Throw a new HttpException with mappedError and mappedError.statusCode using throwError(() => new HttpException(...)).
NestJS
Hint

Use throwError(() => new HttpException(...)) to rethrow the mapped error.

4
Apply the ExceptionMappingInterceptor to a controller method
Create a controller class called AppController with a method getHello that throws an error with message 'Something went wrong'. Import Controller, Get, and UseInterceptors from @nestjs/common. Apply the ExceptionMappingInterceptor to the getHello method using @UseInterceptors(ExceptionMappingInterceptor).
NestJS
Hint

Use @UseInterceptors(ExceptionMappingInterceptor) above the method to apply the interceptor.

Practice

(1/5)
1. What is the main purpose of an ExceptionMappingInterceptor in NestJS?
easy
A. To catch exceptions and transform them into user-friendly responses
B. To log all incoming HTTP requests
C. To validate incoming request data automatically
D. To manage database connections

Solution

  1. Step 1: Understand the role of interceptors

    Interceptors in NestJS can modify requests or responses and handle errors.
  2. Step 2: Identify the function of exception mapping

    An ExceptionMappingInterceptor specifically catches exceptions and converts them into consistent, user-friendly API responses.
  3. Final Answer:

    To catch exceptions and transform them into user-friendly responses -> Option A
  4. Quick Check:

    Exception mapping = user-friendly error response [OK]
Hint: Exception interceptors catch errors and format responses [OK]
Common Mistakes:
  • Confusing interceptors with middleware for logging
  • Thinking interceptors validate data automatically
  • Assuming interceptors manage database connections
2. Which RxJS operator is commonly used inside an ExceptionMappingInterceptor to handle errors?
easy
A. map
B. filter
C. tap
D. catchError

Solution

  1. Step 1: Recall RxJS operators for error handling

    The catchError operator is designed to catch errors in an observable stream.
  2. Step 2: Match operator to interceptor usage

    ExceptionMappingInterceptor uses catchError to catch exceptions and transform them.
  3. Final Answer:

    catchError -> Option D
  4. Quick Check:

    RxJS error handling = catchError [OK]
Hint: Use catchError to catch and transform errors in observables [OK]
Common Mistakes:
  • Using map which transforms data but doesn't catch errors
  • Confusing filter with error handling
  • Using tap which is for side effects, not error catching
3. Given this ExceptionMappingInterceptor code snippet, what will be the output if the handler throws an error?
intercept(context, next) {
  return next.handle().pipe(
    catchError(err => {
      return throwError(() => new BadRequestException('Mapped error'));
    }),
  );
}
medium
A. The original error is sent to the client
B. No error is sent; the request succeeds silently
C. A BadRequestException with message 'Mapped error' is sent to the client
D. A syntax error occurs and the app crashes

Solution

  1. Step 1: Analyze the catchError block

    When an error occurs, catchError catches it and returns a new BadRequestException with a custom message.
  2. Step 2: Understand the effect on the client response

    The client receives the new BadRequestException with message 'Mapped error' instead of the original error.
  3. Final Answer:

    A BadRequestException with message 'Mapped error' is sent to the client -> Option C
  4. Quick Check:

    Error replaced by BadRequestException [OK]
Hint: catchError replaces original error with mapped exception [OK]
Common Mistakes:
  • Thinking original error passes through unchanged
  • Assuming no error is sent and request succeeds
  • Confusing syntax error with runtime error
4. Identify the error in this ExceptionMappingInterceptor code:
intercept(context, next) {
  return next.handle().pipe(
    catchError(err => {
      throw new HttpException('Error occurred', 400);
    }),
  );
}
medium
A. No error; code is correct
B. Using throw inside catchError instead of returning an observable error
C. Incorrect status code 400 instead of 500
D. Missing import for HttpException

Solution

  1. Step 1: Understand catchError usage

    Inside catchError, you must return an observable error, not throw an error directly.
  2. Step 2: Identify correct error handling

    The code should return throwError(() => new HttpException(...)) instead of throwing.
  3. Final Answer:

    Using throw inside catchError instead of returning an observable error -> Option B
  4. Quick Check:

    catchError must return observable error, not throw [OK]
Hint: Return throwError inside catchError, don't throw directly [OK]
Common Mistakes:
  • Throwing error directly inside catchError
  • Ignoring observable error return requirement
  • Assuming status code 400 is wrong here
5. You want to create an ExceptionMappingInterceptor that converts all QueryFailedError exceptions into BadRequestException with a custom message, but lets other exceptions pass unchanged. Which code snippet correctly implements this behavior?
hard
A. return next.handle().pipe(catchError(err => { if (err instanceof QueryFailedError) { return throwError(() => new BadRequestException('Invalid query')); } return throwError(() => err); }));
B. return next.handle().pipe(catchError(err => { if (err instanceof QueryFailedError) { throw new BadRequestException('Invalid query'); } throw err; }));
C. return next.handle().pipe(catchError(err => { if (err.name === 'QueryFailedError') { return new BadRequestException('Invalid query'); } return err; }));
D. return next.handle().pipe(catchError(err => { if (err instanceof BadRequestException) { return throwError(() => new QueryFailedError()); } return throwError(() => err); }));

Solution

  1. Step 1: Check error type and return observable error

    The interceptor must check if the error is a QueryFailedError instance and return a new BadRequestException wrapped in throwError.
  2. Step 2: Pass other errors unchanged as observable errors

    Other errors must be re-thrown as observable errors using throwError to keep the stream consistent.
  3. Final Answer:

    Option A correctly checks error type and returns observable errors properly -> Option A
  4. Quick Check:

    Use instanceof + throwError for error mapping [OK]
Hint: Use instanceof and return throwError for mapped and original errors [OK]
Common Mistakes:
  • Throwing errors directly inside catchError
  • Returning error objects instead of observable errors
  • Checking error name string instead of instanceof
  • Swapping error types incorrectly
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard