-
Notifications
You must be signed in to change notification settings - Fork 443
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
fix(linear-retries): [nan-2309] handle linear case #3108
base: master
Are you sure you want to change the base?
fix(linear-retries): [nan-2309] handle linear case #3108
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we indeed have headers I would suggest something else
"x-complexity": "520",
"x-ratelimit-complexity-limit": "1000000",
"x-ratelimit-requests-remaining": "0",
"x-ratelimit-requests-reset": "1733302464386",
"x-ratelimit-complexity-reset": "1733302464386",
We should change the if in retry
to search for headers whatever the status code
…of github.com:NangoHQ/nango into khaliq/nan-2309-handle-non-standard-linear-rate-limit
Thanks, agreed + less code. Updated with 47becfa |
@@ -259,7 +259,8 @@ class ProxyService { | |||
(error.response?.status === 403 && error.response.headers['x-ratelimit-remaining'] && error.response.headers['x-ratelimit-remaining'] === '0') || | |||
error.response?.status === 429 || | |||
['ECONNRESET', 'ETIMEDOUT', 'ECONNABORTED'].includes(error.code as string) || | |||
config.retryOn?.includes(Number(error.response?.status)) | |||
config.retryOn?.includes(Number(error.response?.status)) || | |||
this.isRetryInHeader(config.provider.proxy?.retry, error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one last question (sorry my suggestion also had some shortcomings):
Are the headers always set or just when we reach rate limit? Here if its always set then all requests will be retried even on regular 400
I guess one missing check that does not exist yet in checking a "remaining headers"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is isRetryInHeader supporting the special case for github 3 lines above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are the headers always set or just when we reach rate limit? Here if its always set then all requests will be retried even on regular 400
Unsure tbh which is why in my initial implementation kept this isolated to Linear to keep the impact low since I don't know how most APIs behave.
I guess one missing check that does not exist yet in checking a "remaining headers"
I don't know what you mean here? Can you clarify?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is isRetryInHeader supporting the special case for github 3 lines above?
No, but I guess we could encapsulate both into updated logic. Few proposals:
- just keep them both hard coded
# github
(error.response?.status === 403 && error.response.headers['x-ratelimit-remaining'] && error.response.headers['x-ratelimit-remaining'] === '0') ||
# linear
(error.response?.status === 400 && error.response.headers['x-ratelimit-requests-remaining'] && error.response.headers['x-ratelimit-requests-remaining'] === '0') ||
- Codify it in the yaml
# github
proxy:
retry:
at: 'x-ratelimit-reset'
remaining: x-ratelimit-remaining
error_code: 403
# linear
proxy:
retry:
at: 'X-RateLimit-Requests-Reset'
remaining: x-ratelimit-requests-remaining
error_code: 400
any thoughts @NangoHQ/engineers?
auth_mode: 'OAUTH2', | ||
proxy: { | ||
retry: { | ||
at: 'x-ratelimit-requests-resets' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would make it very different from the real header name. It took me a few seconds to spot the extra s
@@ -505,6 +505,97 @@ describe('Proxy service Construct URL Tests', () => { | |||
expect(diff).toBeGreaterThan(1000); | |||
expect(diff).toBeLessThan(2000); | |||
}); | |||
|
|||
it('Should retry based on the header even if the error code is not a 429', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we wrap those new tests in their own describe
so you can instanciate the mockAxiosError only once?
Linear sends back a 4xx status code with a
RATELIMITED
string in the body. Currently this doesn't get picked up by our retry logic. Searching using the headers will retry even if it isn't a strict 429.NAN-2309
Test by mimicing a response that is like the linear response