{"id":44664906,"url":"https://github.com/narando/nest-axios-interceptor","last_synced_at":"2026-02-15T00:19:01.457Z","repository":{"id":37964488,"uuid":"262397712","full_name":"narando/nest-axios-interceptor","owner":"narando","description":"Easily manage Interceptors for your Nestjs HttpServices","archived":false,"fork":false,"pushed_at":"2026-02-08T01:49:07.000Z","size":2038,"stargazers_count":50,"open_issues_count":12,"forks_count":11,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-08T09:49:29.606Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://npmjs.com/package/@narando/nest-axios-interceptor","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/narando.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-05-08T18:22:40.000Z","updated_at":"2025-01-27T10:00:29.000Z","dependencies_parsed_at":"2024-03-11T04:26:34.855Z","dependency_job_id":"2972e7c6-71e9-4534-83f8-5424fabe0870","html_url":"https://github.com/narando/nest-axios-interceptor","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/narando/nest-axios-interceptor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narando%2Fnest-axios-interceptor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narando%2Fnest-axios-interceptor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narando%2Fnest-axios-interceptor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narando%2Fnest-axios-interceptor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/narando","download_url":"https://codeload.github.com/narando/nest-axios-interceptor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narando%2Fnest-axios-interceptor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29461686,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T22:42:09.113Z","status":"ssl_error","status_checked_at":"2026-02-14T22:42:05.053Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-15T00:18:59.529Z","updated_at":"2026-02-15T00:19:01.448Z","avatar_url":"https://github.com/narando.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @narando/nest-axios-interceptor\n\n\u003cp align=\"center\"\u003e\n    Easily build and configure \u003ca href=\"https://github.com/axios/axios#interceptors\" target=\"blank\"\u003eaxios interceptors\u003c/a\u003e for the NestJS \u003ca href=\"https://docs.nestjs.com/techniques/http-module\" target=\"blank\"\u003eHttpModule/HttpService\u003c/a\u003e.\n\u003cp align=\"center\"\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://www.npmjs.com/package/@narando/nest-axios-interceptor\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@narando/nest-axios-interceptor.svg\" alt=\"NPM Version\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/@narando/nest-axios-interceptor\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/npm/l/@narando/nest-axios-interceptor.svg\" alt=\"Package License\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/@narando/nest-axios-interceptor\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/@narando/nest-axios-interceptor.svg\" alt=\"NPM Downloads\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/narando/nest-axios-interceptor/actions?query=workflow%3A%22CI%22\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/narando/nest-axios-interceptor/ci.yaml?branch=main\" alt=\"CI Status\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Features\n\n- Define axios interceptors\n- Register interceptor on `HttpService.axiosRef`\n- Type-safe handling of custom options in request config\n\n## Usage\n\n### Installation\n\nInstall this module:\n\n```shell\n$ npm i @narando/nest-axios-interceptor\n```\n\n### Creating an `AxiosInterceptor`\n\nCreate a new module and import the `HttpModule`:\n\n```typescript\n// cats.module.ts\nimport { HttpModule, HttpService } from \"@nestjs/axios\";\n\n@Module({\n  imports: [HttpModule],\n  providers: [CatsService],\n})\nexport class CatsModule {}\n```\n\nBootstrap your new interceptor with this boilerplate:\n\n```typescript\n// logging.axios-interceptor.ts\nimport { Injectable } from \"@nestjs/common\";\nimport { HttpService } from \"@nestjs/axios\";\nimport type { AxiosResponse, InternalAxiosRequestConfig } from \"axios\";\nimport {\n  AxiosInterceptor,\n  AxiosFulfilledInterceptor,\n  AxiosRejectedInterceptor,\n} from \"@narando/nest-axios-interceptor\";\n\n@Injectable()\nexport class LoggingAxiosInterceptor extends AxiosInterceptor {\n  constructor(httpService: HttpService) {\n    super(httpService);\n  }\n\n  // requestFulfilled(): AxiosFulfilledInterceptor\u003cInternalAxiosRequestConfig\u003e {}\n  // requestRejected(): AxiosRejectedInterceptor {}\n  // responseFulfilled(): AxiosFulfilledInterceptor\u003cAxiosResponse\u003e {}\n  // responseRejected(): AxiosRejectedInterceptor {}\n}\n```\n\nBy default, the interceptor uses identity functions (no-op) for all 4 possible events.\n\nTo add your behaviour, override the class methods for the events you want to handle and return a function that will be used in the interceptor.\n\n```typescript\n// logging.axios-interceptor.ts\n@Injectable()\nexport class LoggingAxiosInterceptor extends AxiosInterceptor {\n  constructor(httpService: HttpService) {\n    super(httpService);\n  }\n\n  requestFulfilled(): AxiosFulfilledInterceptor\u003cInternalAxiosRequestConfig\u003e {\n    return (config) =\u003e {\n      // Log outgoing request\n      console.log(`Request: ${config.method} ${config.path}`);\n\n      return config;\n    };\n  }\n\n  // requestRejected(): AxiosRejectedInterceptor {}\n  // responseFulfilled(): AxiosFulfilledInterceptor\u003cAxiosResponse\u003e {}\n  // responseRejected(): AxiosRejectedInterceptor {}\n}\n```\n\n### Setting custom options to the request config\n\nIf you want to pass-through data from on interceptor function to another, add it to the request config object.\n\nFirst, define your new request config type. To avoid conflicts with other interceptors, we will define a Symbol and use it as the object key:\n\n```typescript\n// logging.axios-interceptor.ts\nconst LOGGING_CONFIG_KEY = Symbol(\"kLoggingAxiosInterceptor\");\n\n// Merging our custom properties with the base config\ninterface LoggingConfig extends InternalAxiosRequestConfig {\n  [LOGGING_CONFIG_KEY]: {\n    id: number;\n  };\n}\n```\n\nNow we have to update the interceptor to use this new config:\n\n```diff\n  // logging.axios-interceptor.ts\n  @Injectable()\n- export class LoggingAxiosInterceptor extends AxiosInterceptor {\n+ export class LoggingAxiosInterceptor extends AxiosInterceptor\u003cLoggingConfig\u003e {\n    constructor(httpService: HttpService) {\n      super(httpService);\n    }\n\n-   requestFulfilled(): AxiosFulfilledInterceptor\u003cInternalAxiosRequestConfig\u003e {\n+   requestFulfilled(): AxiosFulfilledInterceptor\u003cLoggingConfig\u003e {\n      return (config) =\u003e {\n        // Log outgoing request\n        console.log(`Request: ${config.method} ${config.path}`);\n\n        return config;\n      };\n    }\n\n    // requestRejected(): AxiosRejectedInterceptor {}\n-   // responseFulfilled(): AxiosFulfilledInterceptor\u003cAxiosResponse\u003e {}\n+   // responseFulfilled(): AxiosFulfilledInterceptor\u003cAxiosResponseCustomConfig\u003cLoggingConfig\u003e\u003e {}\n    // responseRejected(): AxiosRejectedInterceptor {}\n  }\n```\n\nWith the updated typing, you can now use the extend configuration:\n\n```typescript\n// logging.axios-interceptor.ts\nconst LOGGING_CONFIG_KEY = Symbol(\"kLoggingAxiosInterceptor\");\n\n@Injectable()\nexport class LoggingAxiosInterceptor extends AxiosInterceptor\u003cLoggingConfig\u003e {\n  constructor(httpService: HttpService) {\n    super(httpService);\n  }\n\n  requestFulfilled(): AxiosFulfilledInterceptor\u003cLoggingConfig\u003e {\n    return (config) =\u003e {\n      const requestId = 1234;\n\n      config[LOGGING_CONFIG_KEY] = {\n        id: requestId,\n      };\n      // Log outgoing request\n      console.log(`Request(ID=${requestId}): ${config.method} ${config.path}`);\n\n      return config;\n    };\n  }\n\n  // requestRejected(): AxiosRejectedInterceptor {}\n\n  responseFulfilled(): AxiosFulfilledInterceptor\u003c\n    AxiosResponseCustomConfig\u003cLoggingConfig\u003e\n  \u003e {\n    return (response) =\u003e {\n      const requestId = response.config[LOGGING_CONFIG_KEY].id;\n      // Log response\n      console.log(`Response(ID=${requestId}): ${response.status}`);\n\n      return response;\n    };\n  }\n\n  // responseRejected(): AxiosRejectedInterceptor {}\n}\n```\n\n### Handling Errors\n\nBy default, the axios error (rejected) interceptors pass the error with type `any`. This is not really helpful as we can't do anything with it.\n\nInternally, axios wraps all errors in a custom object `AxiosError`. We can use the class method `isAxiosError` to assert that the passed error is indeed of type `AxiosError`, and then process it how we want:\n\n```typescript\n// logging.axios-interceptor.ts\n\n@Injectable()\nexport class LoggingAxiosInterceptor extends AxiosInterceptor {\n  constructor(httpService: HttpService) {\n    super(httpService);\n  }\n\n  // requestFulfilled(): AxiosFulfilledInterceptor\u003cInternalAxiosRequestConfig\u003e {}\n  // requestRejected(): AxiosRejectedInterceptor {}\n  // responseFulfilled(): AxiosFulfilledInterceptor\u003cAxiosResponse\u003e {}\n\n  responseRejected(): AxiosRejectedInterceptor {\n    return (err) =\u003e {\n      if (this.isAxiosError(err)) {\n        const { config, response } = err;\n\n        console.log(\n          `Error ${response.status} in request \"${config.method} ${config.path}`\n        );\n      } else {\n        console.error(\"Unexpected generic error\", err);\n      }\n\n      throw err;\n    };\n  }\n}\n```\n\n## Upgrading\n\n### Version Compatibility\n\n| nest-axios-interceptor | @nestjs/axios | @nestjs    |\n| ---------------------- |---------------|------------|\n| 3.x                    | 2.x \u0026 3.x     | 9.x \u0026 10.x |\n| 2.x                    | 1.x           | 8.x        |\n| 1.x                    | 0.x           | 7.x        |\n\n### v2 to v3\n\nVersion 3 requires:\n\n- @nestjs/axios \u003e 2.0.0\n- @nestjs \u003e 9.0.0\n\nThe axios internal types for request configs changed (`AxiosRequestConfig` -\u003e `InternalAxiosRequestConfig`), and you need to update your types to match.\n\nIf you do not use custom configs, you can use this diff:\n\n```diff\n // logging.axios-interceptor.ts\n import { Injectable } from \"@nestjs/common\";\n import { HttpService } from \"@nestjs/axios\";\n-import type { AxiosResponse, AxiosRequestConfig } from \"axios\";\n+import type { AxiosResponse, InternalAxiosRequestConfig } from \"axios\";\n import {\n   AxiosInterceptor,\n   AxiosFulfilledInterceptor,\n   AxiosRejectedInterceptor,\n } from \"@narando/nest-axios-interceptor\";\n\n @Injectable()\n export class LoggingAxiosInterceptor extends AxiosInterceptor {\n   constructor(httpService: HttpService) {\n     super(httpService);\n   }\n\n-  // requestFulfilled(): AxiosFulfilledInterceptor\u003cAxiosRequestConfig\u003e {}\n+  // requestFulfilled(): AxiosFulfilledInterceptor\u003cInternalAxiosRequestConfig\u003e {}\n   // requestRejected(): AxiosRejectedInterceptor {}\n   // responseFulfilled(): AxiosFulfilledInterceptor\u003cAxiosResponse\u003e {}\n   // responseRejected(): AxiosRejectedInterceptor {}\n }\n```\n\nIf you use custom configs, you also need to change the custom config:\n\n```diff\n // logging.axios-interceptor.ts\n const LOGGING_CONFIG_KEY = Symbol(\"kLoggingAxiosInterceptor\");\n\n // Merging our custom properties with the base config\n-interface LoggingConfig extends AxiosRequestConfig {\n+interface LoggingConfig extends InternalAxiosRequestConfig {\n   [LOGGING_CONFIG_KEY]: {\n     id: number;\n   };\n }\n```\n\n## License\n\nThis repository is published under the [MIT License](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnarando%2Fnest-axios-interceptor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnarando%2Fnest-axios-interceptor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnarando%2Fnest-axios-interceptor/lists"}