Skip to content

fix(web-api): retry responses interrupted while reading the body - #2739

Open
ujjawal-yadav wants to merge 1 commit into
slackapi:mainfrom
ujjawal-yadav:fix/2738-retry-interrupted-response-body
Open

fix(web-api): retry responses interrupted while reading the body#2739
ujjawal-yadav wants to merge 1 commit into
slackapi:mainfrom
ujjawal-yadav:fix/2738-retry-interrupted-response-body

Conversation

@ujjawal-yadav

Copy link
Copy Markdown

Summary

Fixes #2738.

makeRequest() wraps fetch in pRetry, but fetch resolves once the response headers arrive. The body was read afterwards by buildResult() — and by postFileUploadsToExternalURL() — outside both the retry loop and the catch that produces a coded WebAPIRequestError. A connection dropped mid-body therefore neither retried nor got an error.code. Under axios the body was materialized inside the retried request, so v7 retried the same interruption.

The fix reads the body inside the retried task and returns a FetchResponse that replays the buffered bytes, so both call sites consume it unchanged. Same shape as the bufferingFetch workaround in the issue, moved inside makeRequest so it also covers a custom fetch.

Notes

Two side effects of the wider task boundary. Both match v7, neither is fixed here — happy to add either if you want it:

  • A concurrency slot is now held until the body is read, rather than freed at the headers. Synthetic worst case (8 requests, maxRequestConcurrency: 4, 200ms bodies): ~322ms on 8.1.1, ~561ms here, ~323ms if the body read moves just outside the queue callback.
  • Retries now repeat a request the server already acted on. Against a permanently-truncating server at retries: 10: 1 request on 8.1.1, 11 here, 2 with a separate one-retry budget for interrupted bodies. Since fix(webhook): do not retry after a successful trigger delivery #2674 narrowed webhook recently, capping this seemed like your call rather than mine.

Validation

  • npm test --workspace=@slack/web-api — 155 passing, including 3 new tests that all fail on main
  • npm test --workspaces — 310 passing
  • npm run lint, npm run build, npm run docs — clean

Requirements

`makeRequest` wraps `fetch` in `pRetry`, but `fetch` resolves as soon as the
response headers arrive. The body was read by `buildResult` (and by
`postFileUploadsToExternalURL`) after `makeRequest` had already returned, so a
connection dropped partway through the body landed outside both the retry loop
and the `catch` that converts failures into `WebAPIRequestError`. Callers saw a
raw `TypeError: terminated` with an undefined `code`, and no retry was attempted.

Read the body inside the retried task instead, returning a `FetchResponse` that
replays the buffered bytes so both call sites keep consuming it as before. This
restores the v7 behaviour, where the body was buffered before the request
promise settled.

Closes slackapi#2738
@ujjawal-yadav
ujjawal-yadav requested a review from a team as a code owner September 10, 2026 17:06
@changeset-bot

changeset-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e134198

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@slack/web-api Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

web-api v8 no longer retries interrupted response bodies

1 participant