feat(js-sdk): support retry-after header#504
Conversation
| fgaApi.check(baseConfig.storeId!, { tuple_key: tupleKey }, { retryParams: { maxRetry: 0 }}) | ||
| ).rejects.toThrow(FgaApiInternalError); | ||
| }); | ||
| it("should throw FgaApiInternalError for 500 error without Retry-After header", async () => { |
There was a problem hiding this comment.
Without the retry header, it should fall back to exponential backoff
| if (status === 429) { | ||
| retryDelayMs = randomTime(iterationCount, config.minWaitInMs); | ||
| } else if (status >= 500 && status !== 501) { | ||
| // For 5xx (except 501), we only retry if Retry-After was present |
There was a problem hiding this comment.
Let's change this so that we fall back to exponential backoff here too
| const secondsValue = parseInt(retryAfterValue, 10); | ||
| if (!isNaN(secondsValue)) { | ||
| const msValue = secondsValue * 1000; | ||
| if (msValue >= 1000 && msValue <= 1800000) { |
There was a problem hiding this comment.
rather than these being hard-coded, now that the go-sdk changes have been merged, you can use the following variables:
- {{maxBackoffTimeInSec}}
| if (msValue >= 1000 && msValue <= 1800000) { | |
| if (msValue > 0 && msValue <= {{retryHeaderMaxAllowableDurationInSec}}) { | |
| } |
| const now = new Date(); | ||
| const delayMs = dateValue.getTime() - now.getTime(); | ||
|
|
||
| if (delayMs >= 1000 && delayMs <= 1800000) { |
There was a problem hiding this comment.
This logic looks repeated, can you extract it to it's own function and reference it above and here?
| const max = Math.ceil(2 ** (loopCount + 1) * minWaitInMs); | ||
| return Math.floor(Math.random() * (max - min) + min); //The maximum is exclusive and the minimum is inclusive | ||
| const calculatedTime = Math.floor(Math.random() * (max - min) + min); | ||
| return Math.min(calculatedTime, 120000); |
There was a problem hiding this comment.
| return Math.min(calculatedTime, 120000); | |
| return Math.min(calculatedTime, {{maxBackoffTimeInSec}}); |
There was a problem hiding this comment.
Defined here:
sdk-generator/config/common/config.base.json
Lines 88 to 89 in 885bdb7
| throw new FgaApiNotFoundError(err); | ||
| } else if (status === 429 || status >= 500) { | ||
| if (iterationCount >= config.maxRetry) { | ||
| } else if (status === 429 || (status >= 500 && status !== 501)) { |
There was a problem hiding this comment.
Can you also make sure we are retrying on network errors?
Currently we do not retry on them: https://github.com/openfga/js-sdk/blob/8fb95c80ff57d10616c0fd60ca1dfc991ce41675/common.ts#L177
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Pre-merge checks and finishing touches✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
e5beab7 to
6bc19e4
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
config/clients/js/template/common.mustache(2 hunks)config/clients/js/template/tests/helpers/nocks.ts.mustache(1 hunks)config/clients/js/template/tests/index.test.ts.mustache(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
config/**/*.mustache
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Validate mustache syntax and variable references across all template files, including CHANGELOG.md.mustache
Files:
config/clients/js/template/tests/helpers/nocks.ts.mustacheconfig/clients/js/template/tests/index.test.ts.mustacheconfig/clients/js/template/common.mustache
config/**/*.{json,mustache}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Never hardcode API keys or credentials in configuration or template files
Files:
config/clients/js/template/tests/helpers/nocks.ts.mustacheconfig/clients/js/template/tests/index.test.ts.mustacheconfig/clients/js/template/common.mustache
🧠 Learnings (1)
📚 Learning: 2025-08-12T14:18:58.827Z
Learnt from: rhamzeh
PR: openfga/sdk-generator#573
File: config/clients/java/config.overrides.json:184-191
Timestamp: 2025-08-12T14:18:58.827Z
Learning: In the OpenFGA SDK generator, templates are inherited from the upstream OpenAPI Generator (openapitools/openapi-generator-cli). Only custom or modified templates need to be explicitly defined in the config overrides files. Base templates like `settings.gradle.mustache` are provided by the upstream generator and don't require override mappings.
Applied to files:
config/clients/js/template/common.mustache
🪛 Gitleaks (8.28.0)
config/clients/js/template/tests/index.test.ts.mustache
[high] 881-881: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
Description
Honor the retry-after header so that a client does not overwhelm the FGA server with requests.
References
Closes: openfga/js-sdk#208
Review Checklist
mainSummary by CodeRabbit
New Features
Bug Fixes
Tests