fix: npm 429 retries - #4427
Conversation
Signed-off-by: anilb <epipav@gmail.com>
PR SummaryMedium Risk Overview
On Reviewed by Cursor Bugbot for commit 818c098. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
|
|
Your PR title doesn't contain a Jira issue key. Consider adding it for better traceability. Example:
Projects:
Please add a Jira issue key to your PR title. |
There was a problem hiding this comment.
Pull request overview
Improves npm ingestion retries by honoring Retry-After and skipping packages completed during earlier Temporal attempts.
Changes:
- Propagates npm rate-limit delay metadata.
- Overrides Temporal retry delays for HTTP 429 responses.
- Skips packages already processed during retried batches.
Review note: Retry-After date values and delays over 900 seconds are not honored. The PR title also lacks the required JIRA key.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
npmPackageState.ts |
Finds packages scanned since activity scheduling. |
types.ts |
Adds retry-delay metadata to fetch errors. |
fetchPackument.ts |
Reads Retry-After from 429 responses. |
activities.ts |
Customizes retries and skips completed work. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: anilb <epipav@gmail.com>
|
@cursor review |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (2)
services/apps/packages_worker/src/npm/activities.ts:126
- The one-hour cap can schedule a retry before the server-stated penalty ends when
Retry-Afterexceeds 3600 seconds. Since this activity has no schedule-to-close timeout and only five attempts, repeated early retries can exhaust the lane while it is still rate-limited. Remove the cap so this branch actually honors the header.
const delaySec = Math.min(Math.max(packumentResult.retryAfterSec ?? 300, 30), 3600) + 5
services/apps/packages_worker/src/npm/fetchPackument.ts:77
0is a valid Retry-After delta, but this converts it toundefined, causing the caller to use the 300-second fallback instead of its 30-second minimum. Preserve zero here so a server that permits an immediate retry does not stall the lane for five minutes.
if (Number.isFinite(seconds)) return seconds > 0 ? Math.ceil(seconds) : undefined
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 563c883. Configure here.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (2)
services/apps/packages_worker/src/npm/fetchPackument.ts:77
Retry-After: 0is a valid delta-seconds value, but this maps it toundefined; the caller then substitutes 300 seconds rather than applying its 30-second safety floor. Preserve zero so this valid response does not cause an unnecessary five-minute pause.
if (Number.isFinite(seconds)) return seconds > 0 ? Math.ceil(seconds) : undefined
services/apps/packages_worker/src/npm/activities.ts:126
- The 3600-second cap can schedule the next request before the server's
Retry-Afterwindow expires, which defeats this retry path and can trigger another 429. Keep the 30-second floor, but do not shorten a valid server-provided delay.
const delaySec = Math.min(Math.max(packumentResult.retryAfterSec ?? 300, 30), 3600) + 5
Signed-off-by: anilb <epipav@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (1)
services/apps/packages_worker/src/npm/fetchPackument.ts:78
Retry-After: 0is a valid delta-seconds value, but this converts it toundefined.ingestOnethen substitutes the 300-second fallback, producing a 305-second retry instead of applying its 30-second safety floor. Preserve zero so the nullish fallback does not replace an explicit server value.
if (Number.isFinite(seconds)) return seconds > 0 ? Math.ceil(seconds) : undefined
No description provided.