fix: retry transient network errors by default - #240
Open
reeshika-h wants to merge 1 commit into
Open
Conversation
The default retryCondition only ever matched HTTP 429, so any network-level failure (DNS resolution failure, connection reset, client-side timeout) with no HTTP response got zero retries out of the box, even though the retry mechanism to handle them already existed and was already tested (retrying via a custom retryCondition already worked). Add a default retryCondition fallback covering ECONNABORTED, ETIMEDOUT, ECONNRESET, EPIPE, and EAI_AGAIN (DNS transient failure) when there is no response - deliberately excluding ENOTFOUND and ECONNREFUSED, which usually indicate a persistent misconfiguration rather than a transient blip. Placed in delivery-sdk-handlers.ts's own defaultConfig rather than contentstack-core.ts's httpClient defaults, since retryResponseErrorHandler is invoked with the raw StackConfig (see contentstack-typescript's stack/contentstack.ts), not client.defaults - a retryCondition set only on the axios instance defaults never reaches the actual retry decision. Verified against the real call pattern, not just isolated unit tests. DX-9991
🔒 Security Scan Results
⏱️ SLA Breach Summary
✅ BUILD PASSED - All security checks passed |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ticket
DX-9991 (follow-up to #239, reviewed/shipped independently)
Problem
The retry mechanism for network-level errors already existed and worked - but only when a custom
retryConditionwas supplied. The defaultretryConditiononly matched HTTP 429, so any network-level error (DNS failure, connection reset, timeout) got zero retries out of the box, even though the SDK already knew how to retry it.Fix
Added a default
retryConditionfallback indelivery-sdk-handlers.ts: retry when there's no response anderror.codeisECONNABORTED,ETIMEDOUT,ECONNRESET,EPIPE, orEAI_AGAIN. ExcludedENOTFOUND/ECONNREFUSED- usually persistent misconfiguration, not transient. This package is used only by the read-only Delivery SDK, so no idempotency risk.Note: initially placed this in
contentstack-core.ts'shttpClientdefaults, but verified end-to-end thatretryResponseErrorHandleris actually called with the rawStackConfig(seecontentstack-typescript'sstack/contentstack.ts), notclient.defaults- so that location was dead code. Moved the fix todelivery-sdk-handlers.ts's owndefaultConfig, which is what actually merges with the caller's config, and re-verified against the real call pattern.Relationship to #239
Separate PR by design - different risk profile (this changes default retry behavior; #239 was a pure classification fix), independently revertable. One side effect: once a retried
ECONNABORTEDexhausts retries, the final error is axios's raw message rather than #239's custom one - still distinct/diagnosable, just different wording. Flagging for awareness, not a regression.Tests
StackConfig, not axios instance defaults).ENOTFOUND/ECONNREFUSEDconfirmed to still not retry by default.retryCondition: () => false, since it was testing the non-retried path.PR description generated by Claude (Sonnet 5) in collaboration with @reeshika-h.