Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue#2609 | Sasha | predictable axios requests #2702

Merged
merged 7 commits into from Mar 1, 2021

Conversation

SashaKoro
Copy link
Contributor

  • axios requests are not delayed by pre-emptive promise creation by default
  • add options to interceptors api ("synchronous" and "runWhen"
  • add documentation and unit tests

@SashaKoro
Copy link
Contributor Author

Issue for context: #2609

@SashaKoro
Copy link
Contributor Author

@chinesedfan Let me know if anything is unclear or needs some extra work. Happy to make changes. 😃

Copy link
Collaborator

@chinesedfan chinesedfan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SashaKoro Really thanks for your work. Left some comments to discuss.

  • Shall we consider the response interceptors someday? How about call as synchronousRequest and requestWhen?
  • In fact, runWhen can be achieved by adding a conditional return statement in the beginning of interceptors. I want to make axios as simple as possible.
  • No need to update dist files, because we will update them together before releasing.

README.md Show resolved Hide resolved
lib/core/Axios.js Outdated Show resolved Hide resolved
lib/core/Axios.js Show resolved Hide resolved
lib/core/Axios.js Show resolved Hide resolved
lib/core/Axios.js Outdated Show resolved Hide resolved
lib/core/Axios.js Outdated Show resolved Hide resolved
lib/core/Axios.js Outdated Show resolved Hide resolved
test/specs/adapter.spec.js Outdated Show resolved Hide resolved
test/specs/interceptors.spec.js Outdated Show resolved Hide resolved
test/specs/interceptors.spec.js Outdated Show resolved Hide resolved
@SashaKoro
Copy link
Contributor Author

SashaKoro commented Jan 31, 2020

@chinesedfan Thanks for the feedback! I will be working through the comments, responding and updating the MR over the next couple of days.

To answer the question of:

"How about call as synchronousRequest and requestWhen?"

I explicitly did not use request in the naming because the interceptors do not always fire requests inside of themselves. Sometimes they are just updating the configuration object, doing logging or updating UI state.

@chinesedfan
Copy link
Collaborator

I explicitly did not use request in the naming because the interceptors do not always fire requests inside of themselves. Sometimes they are just updating the configuration object, doing logging or updating UI state.

@SashaKoro My fault. axios.interceptors.request/response are both instances of InterceptorManager. And I have replied to other questions for you.

@SashaKoro
Copy link
Contributor Author

To answer:

"In fact, runWhen can be achieved by adding a conditional return statement in the beginning of interceptors."

I put runWhen as a separate config option because axios needs to know if the interceptor will run before its executed. This is in the case where asynchronous interceptors that do not need to run can be filtered out prior to going into sync or async flows.

@SashaKoro
Copy link
Contributor Author

To answer:

Shall we consider the response interceptors someday?

Yeah, that's a good call. Do you mind if I look at that as part of a separate MR? Just to wrap this one up (because that story could have its own unknowns).

- axios requests are not delayed by pre-emptive promise creation by default
- add options to interceptors api ("synchronous" and "runWhen")
- add documentation and unit tests
@SashaKoro
Copy link
Contributor Author

@chinesedfan I've updated the pull request with the changes requested.

Copy link
Collaborator

@chinesedfan chinesedfan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SashaKoro Resolved or replied old conversations. And left new comments for your updates.

Do you mind if I look at that as part of a separate MR? Just to wrap this one up (because that story could have its own unknowns).

Sure. I think less people care about that.

README.md Outdated Show resolved Hide resolved
lib/core/Axios.js Outdated Show resolved Hide resolved
test/specs/interceptors.spec.js Outdated Show resolved Hide resolved
test/specs/adapter.spec.js Show resolved Hide resolved
@SashaKoro
Copy link
Contributor Author

@chinesedfan Pull request updated with requested changes

@SashaKoro
Copy link
Contributor Author

@chinesedfan I will address your latest comments soon. This week has been pretty busy.

@SashaKoro
Copy link
Contributor Author

@chinesedfan Pull request updated with requested changes.

@SashaKoro
Copy link
Contributor Author

@chinesedfan Pull request updated with the new unit tests and the removed requestCancelled check.

Copy link
Collaborator

@chinesedfan chinesedfan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SashaKoro No other reviewers now. After days, I checked this pull request again and found 2 new points.

chain.unshift(interceptor.fulfilled, interceptor.rejected);
if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {
return;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As runWhen is executed immediately, we need to try/catch of it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused on this one. What do we want to do in the catch if the runWhen function fails? The function is provided by the consumer so we don't know what kind of errors it might throw. I would think we just want the program to fail at that point.

The axios configuration accepts other consumer provided functions such as validateStatus and paramsSerializer. Calls to those functions are not wrapped in try/catch blocks.

try {
newConfig = onFulfilled(newConfig);
} catch (error) {
onRejected(error);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If onRejected had solved the error, we should continue the loop. If not, should drop to the next onRejected.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this would make the functionality different from the asynchronous behavior then.

When we have async interceptors we do a promise chain:

promise = promise.then(chain.shift(), chain.shift());

When any interceptor throws in a chained promise, the whole thing errors out.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SashaKoro Sorry for my long long latency. I mean,

var f = function(name) {
    return function(...args) {
        console.log(name, args)
    }
}

Promise.reject('bad')
     .then(f('f1'), f('f2'))
     .then(f('f3'), f('f4'))

// outputs
f2 [ 'bad' ]
f3 [ undefined ]

Even though the chain has an error, but f2 can resolve it and make the loop go on.

@SashaKoro
Copy link
Contributor Author

@chinesedfan Hey! I will try to address the requested changes as soon as I can. Been pretty busy.

@SashaKoro
Copy link
Contributor Author

@chinesedfan Hey, just replied to your comments. Sorry for the long delay. Things are pretty hectic.

@SashaKoro
Copy link
Contributor Author

@chinesedfan Checking in on the status of this merge request.

@BruceHubbard
Copy link

@chinesedfan Did you see @SashaKoro's comments? We're still running on a fork of this library for now until this MR gets merged in.

@briganti
Copy link

@chinesedfan @yasuf any plan on merging this PR?

@SashaKoro
Copy link
Contributor Author

SashaKoro commented Feb 23, 2021

@chinesedfan @yasuf @jasonsaayman

It's been a while and this cropped back up on my radar again.

Look, I know this is a big change but its also a valuable change. This merge request is already up to 75 comments and I've come back around and updated things several times. My last comments from 10 months did not receive a response. What is preventing this merge request from getting merged? (Besides getting the branch up to date)

@jasonsaayman
Copy link
Member

@SashaKoro I will look at this in the evening my time and see if we can merge it. Can you tell me if this is up to date with the latest Axios version? Also, are we breaking any backward compatibility here? I have updated the branch so let's see if that comes out successful.

@SashaKoro
Copy link
Contributor Author

SashaKoro commented Feb 23, 2021

@jasonsaayman

Hey Jay. Thanks for the quick reply. I'm gonna get myself up to speed with the latest axios version + backward compatibility this evening / tomorrow and get back to you.

@SashaKoro
Copy link
Contributor Author

SashaKoro commented Feb 25, 2021

@jasonsaayman

I've done a thorough look through the axios commits to master since the original merge request timeline and did not find any potential issues. The merge request should break no backward capabilities.

@jasonsaayman jasonsaayman self-assigned this Mar 1, 2021
@jasonsaayman jasonsaayman added this to the v0.22.0 milestone Mar 1, 2021
@jasonsaayman jasonsaayman merged commit 62d6256 into axios:master Mar 1, 2021
@jasonsaayman jasonsaayman added this to Done in v0.22.0 Mar 17, 2021
jeremyxu2010 pushed a commit to jeremyxu2010/axios that referenced this pull request Jul 2, 2021
Glandos added a commit to Glandos/vue-auth-plugin that referenced this pull request Sep 8, 2021
Since axios/axios#2702 (in axios 0.21.2) it is possible to avoid delay in requests.
Interceptors set up by vue-auth are global, and are delaying every other callers.
jeffberry pushed a commit to jeffberry/axios that referenced this pull request Oct 16, 2021
Updates Typescript definition file to include types for the interceptor options that were added in axios#2702 so that Typescript users are able to safely consume this feature.
yepitschunked added a commit to yepitschunked/axios-retry that referenced this pull request Nov 4, 2021
Axios recently added an option to specify whether a request interceptor is synchronous. See axios/axios#2702.
var chain = [dispatchRequest, undefined];

Array.prototype.unshift.apply(chain, requestInterceptorChain);
chain.concat(responseInterceptorChain);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chinesedfan @SashaKoro Here is the bug of issue #4036! The concat method does not change the existing arrays, but instead returns a new array. It cause response interceptors not append into chain!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but it has been fixed in #4013 and released in v0.21.3.

mbargiel pushed a commit to mbargiel/axios that referenced this pull request Jan 27, 2022
* issue#2609 | Sasha | predictable axios requests

- axios requests are not delayed by pre-emptive promise creation by default
- add options to interceptors api ("synchronous" and "runWhen")
- add documentation and unit tests

* issue#2609 | Sasha | pull request feedback changes

* issue#2609 | Sasha | additional feedback changes

* issue#2609 | Sasha | put back try/catch

* issue#2609 | Sasha | add 2 adapter unit tests

- remove check for requestCancelled

Co-authored-by: ak71845 <alexandre.korotkov@kroger.com>
Co-authored-by: Xianming Zhong <chinesedfan@qq.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
v0.22.0
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

7 participants