Skip to content

fix: bound unbounded fetch calls with 30s AbortSignal.timeout - #169

Open
hermiondev wants to merge 1 commit into
alchemyplatform:masterfrom
hermiondev:fix/rest-timeout
Open

hermiondev wants to merge 1 commit into
alchemyplatform:masterfrom
hermiondev:fix/rest-timeout

Conversation

@hermiondev

Copy link
Copy Markdown

Problem

Two send paths in this repo issue fetch with no timeout and no AbortSignal, so any request whose upstream accepts the TCP connection but never replies hangs the caller's promise forever:

  • src/web3-adapter/alchemySendHttp.ts:16 — the JSON-RPC HTTP sender. Every web3.eth call through an HTTP provider funnels here.
  • src/web3-adapter/sendRestPayload.ts:70 — the REST payload sender. Worse here: the unbounded fetch sits inside the maxRetries loop, so each stalled attempt blocks indefinitely and the retry logic never gets a chance to run.

Reproduced on the published npm artifact @alch/alchemy-web3@1.4.7: provider pointed at a stall server (accepts connections, never responds) → provider.send({method:'eth_blockNumber'}) still pending after a 15s watchdog (exit 124). Control: with the signal below, the same request rejects with AbortError at ~30s.

Fix

Bound both fetch call sites with AbortSignal.timeout(30000), feature-detected so fetch-ponyfill and older runtimes (React Native, browsers without AbortSignal.timeout) keep working exactly as before — the option key is simply omitted when unsupported.

Validation

  • yarn jest on Node 20.20.2: 3 suites / 8 pass / 0 fail (unchanged from base).
  • Behavior probe: stall-server hang before fix (never settles), clean AbortError after.

Related: same defect class found + PR'd in sibling repos — alchemyplatform/aa-sdk#2571 (AlchemyRestClient), and archived alchemy-sdk-js (DEFAULT_REQUEST_TIMEOUT = 0).

- alchemySendHttp.ts: JSON-RPC HTTP sender had no timeout -> hangs
  forever if upstream accepts TCP but never replies
- sendRestPayload.ts: same pattern in REST payload sender (also
  amplifies: inside maxRetries loop, each stalled attempt is unbounded)

Guarded feature-detect (AbortSignal.timeout) keeps fetch-ponyfill /
older runtime compatibility.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant