fix(maticjs): retry transient network errors via a shared retryTransient helper - #481
Merged
Merged
Conversation
MaximusHaximus
marked this pull request as ready for review
June 26, 2026 13:04
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
shan8851
previously approved these changes
Jun 26, 2026
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
MaximusHaximus
force-pushed
the
worktree-retry-transient-fetch
branch
from
June 26, 2026 13:15
d508eba to
506f588
Compare
The config-store fetch (ABIManager.init -> HttpRequest) had no retry, so a stale keep-alive socket (Node 19+ keeps HTTP connections alive by default) surfaced as a node-fetch "Premature close" / ECONNRESET and — masked by Web3SideChainClient.init — looked like "network mainnet - v1 is not supported". Extract the retry/backoff + transient-error classification that getReceiptProof implemented inline into a shared `retryTransient` helper, and use it on both the metadata fetch and the receipt-proof RPC reads. The shared classifier also recognises node-fetch's "Premature close" (message-based), which the old inline predicate — code-only — did not match, so the metadata path is now actually covered. Full-jitter exponential backoff, defaults preserved from the previous inline implementation.
MaximusHaximus
force-pushed
the
worktree-retry-transient-fetch
branch
from
June 26, 2026 13:16
506f588 to
9dc06a2
Compare
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.
Problem
The config-store fetch in
ABIManager.init(viaHttpRequest) had no retry. Node.js 19+ keeps HTTP(S) connections alive by default, so when the server closes an idle keep-alive socket, the next request reusing it dies with a transient error — observed as a node-fetchPremature closewhile readinghttps://static.polygon.technology/network/mainnet/v1/index.json.Web3SideChainClient.initthen masked it asnetwork mainnet - v1 is not supported(fixed in #477 to surface the cause — which is how we caught this). It's intermittent and load-sensitive, so it hit CI ~80% of the time while passing locally.getReceiptProofalready documents and handles this exact failure class (ECONNRESET, …) with a bespoke inline retry — but that logic lived only inproof_util.ts, and its predicate was code-only, so it wouldn't even have matchedPremature close(aFetchErrorwhose message, notcode, carries the cause).Fix — one shared helper, no duplicated retry logic
New
utils/retry.ts:isTransientNetworkError(err)— the known transient codes (ECONNRESET,ENOTFOUND,ECONNREFUSED,ETIMEDOUT,EPIPE,ERR_STREAM_PREMATURE_CLOSE) plus message-based matching for node-fetch'sPremature close/socket hang up(the gap that let this bug through).retryTransient(fn, opts)— full-jitter exponential backoff (defaults preserved from the previous inline implementation: 2 retries,50 * 2^icapped at 250ms).Wired in:
http_request.ts—get/postwrap their fetch inretryTransient(transient connection failures retried; HTTP-status errors stay non-retried).proof_util.ts— the inlineattempt()recursion ingetReceiptProofis replaced byretryTransient(() => web3.getTransactionReceipt(hash)). Behaviour preserved, and it now also coversPremature close.Tests
tests/retry.test.ts(6 cases): classification incl.Premature close; retry-then-succeed; no-retry on application errors; give-up-and-rethrow. Full package suite: 35 passed. Typecheck + lint + webpack build green.