-
Notifications
You must be signed in to change notification settings - Fork 452
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
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?
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.
the second one looks cleaner but it make providers.yaml more complex. I don't feel strongly either way
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.
Option 2 seems correct and not too hard to implement, I would love it 👍🏻
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.
Implemented option 2 with b94e844
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
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.
Updated
@@ -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?
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.
Updated
…9-handle-non-standard-linear-rate-limit
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.
Super clean 👌🏻
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