02 / 06

What is the difference between tap(), map(), and catchError() in an interceptor's RxJS pipeline?

tap() is a side-effect operator that does not change the emitted value — used for logging and auditing. map() transforms the emitted value — used to wrap responses or rename fields. catchError() catches errors in the stream — used to remap domain exceptions into HTTP exceptions or provide fallback values.

All three operators in one interceptor
When to use each operator:
  1. 1

    tap(fn) — logging, metrics, auditing. The stream value passes through unchanged.

  2. 2

    map(fn) — response wrapping, field renaming, stripping sensitive properties.

  3. 3

    catchError(fn) — remapping lower-level errors (TypeORM, Mongoose) into NestJS HTTP exceptions.

  4. 4

    Operators execute in the order they are listed in pipe().

  5. 5

    catchError must return an Observable — use throwError(() => new Error()) to re-throw.