ctimmerm / axios-mock-adapter

Axios adapter that allows to easily mock requests

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

passthrough onNoMatch does not work with axios 1.2.0 or above

teetotum opened this issue · comments

I maintain axios-response-mock which covers a similar use-case as does axios-mock-adapter.
My lib broke with axios version 1.2.0 with regard to passthrough requests; I got runtime errors in the vein of 'originalAdapter is not a function'.
I finished analysing the issue and thought I let you know what I found out; because I'm quite sure it broke your lib in the very same way.

The following section contains my analysis and thoughts.

Analysis

  • in axios v 1.1.3 (and below) the original default adapter is a function
  • (in axios v 1.2.0-alpha.1 the original default adapter is still a function)
  • in axios v 1.2.0 (and above) the original default adapter is an array ['xhr', 'http']

the change was introduced with #5277
(Changelog entry: refactor: allowing adapters to be loaded by name #5277)
(merged November 22nd) and released with v1.2.0 on November 22nd

If a custom adapter now wants to selectively decide which requests to handle itself and which requests to passthrough to the default adapter / delegate to the default adapter, how best would it now obtain a reference to the default adapter?

Before the change, a custom adapter could secure a reference to the default adapter via axiosInstance.defaults.adapter and call it later to delegate.

Example:

this.originalAdapter = axiosInstance.defaults.adapter;
axiosInstance.defaults.adapter = this._processRequest.bind(this);

// and later
if (matchedRoute)
    return this._respond(matchedRoute, config);
else
    return this.originalAdapter(config);

I opened a discussion on the axios github repo.

What options do I have now?

  • re-implement and ship my own xhr and http adapter? no, not feasible.
  • import the axios v1.2.0 xhr and http adapters and include in my library bundle? could work. would only consider this as a temporary solution
  • refactor response-mock implementation to work in two separate steps: custom interceptor to check if a mocked route matches, and if that's the case add mock adapter to the options, which means all non-matching routes are handled normally. This is an elegant solution, but I would prefer a pure adapter approach as soon as axios adds a feature to delegate to the default adapter.

Conclusion:

Today I published version 0.2.2-alpha.1 of axios-response-mock and it seems I could fix the issue. But it is only a temporary stopgap.
When axios starts supporting a stable way to obtain a reference to the defaultAdapter I will change my fix; if the axios maintainers dismiss the feature request I will probably refactor my lib into the two steps approach sketched above.

Hi! I am experimenting this Issue with the package. Is there a workaround while still using the library? For now I downgraded axios to 1.1.3 and its functional.
Could I help in some way?

commented

@nicolascampbell The only workaround I'm aware of is to stay below axios v1.2.0 (the release v1.2.0-alpha.1 should also work though) if you still want to be able to passthrough requests.

I've create this issue in axios: axios/axios#5474
Here you absolutely need to access to getAdapter() method to access original adapter, as it is not always a function.

by waiting this you can at least manage the support of the array internally, or temporary do an import of axios/lib/adapters/adapter.js to access getAdapter method

A fix for this module is in #363

hello @marcbachmann any update on the fix? :)

Sadly not yet. The PR is ready to merge

@marcbachmann Today I discovered that axios made getAdapter accessible (the feature PR was merged Aug 9, 2023 and released with 1.5.0 Aug 26, 2023).

I will now revisit my workaround in my library and fix it properly.
Not sure if you want to refactor your fix for axios-mock-adapter now to use getAdapter; which would allow you to get rid of the code that currently strips the interceptors and transformations and fields a separate call to axios.