Skip to content

fix(integrations): report a stalled response body as a timeout (#176) - #209

Merged
baldurpan merged 5 commits into
mainfrom
176-a-body-that-stalls-past-the-15s-timeout-is-not
Nov 1, 2026
Merged

baldurpan merged 5 commits into
mainfrom
176-a-body-that-stalls-past-the-15s-timeout-is-not

Conversation

@baldurpan

Copy link
Copy Markdown
Contributor

Closes #176

What changed

The 15s AbortSignal.timeout passed to fetch also bounds reading the body. Linear, GitHub and Jira translated a TimeoutError only at the fetch call, so a body that stalled after the headers missed TIMEOUT_MESSAGE and came out with code failed. It now reports <what> did not answer within 15s, as ClickUp has since #175.

  • Linear: readBody rethrows a timeout through a shared timeoutError. A real parse failure still returns undefined.
  • GitHub and Jira: every body read goes through readGitHubBody or readJiraBody, and a non-timeout read error is rethrown unchanged.
  • Wider than the issue: it also covers .text() on non-OK responses (githubFailure, fetchJiraIssue, jiraAssignFailure), and the assign reads. These had the same defect.
  • Release note: .changeset/stalled-body-timeout.md, patch, level confirmed by the maintainer.

Verification

Gate 1 was run on top of #204, which fixed the main failures in #203. pnpm check, pnpm typecheck, pnpm --filter docs typecheck, pnpm build, pnpm test (2094 passed), pnpm docs:test (69 passed) and the test-markers check all exited 0. pnpm check was re-run after the note was added.

  • Mutation checks: forcing isTimeout to true fails exactly the 2 new parse-failure tests. Removing the body-read guards fails 9 stalled-body tests across all three integrations.
  • Real server: the built fetchGitHubLogin against a local server that sends headers and half a body, then stalls, gives GitHub: /user did not answer within 15s. for both a 200 and a 500. Linear and Jira are covered by mocks only.

Review

The reviewer subagent returned FAIL on the first pass (no release note; parse failure unpinned for GitHub and Jira), then PASS WITH NOTES once both were fixed.

Non-blocking behaviour worth reading:

  • Pull-request head branch lookup: fetchGitHubPullRequestHeadBranch keeps its catch-all, so a stalled body there gives no suggested branch rather than a timeout. The lookup only improves a refusal message, and a stalled fetch there was already swallowed the same way. That makes the guard at that read a no-op.
  • Linear non-OK answers: readBody runs before the status check, so a 429 or other non-OK answer whose body stalls now reports a timeout rather than the rate-limit or failed message. No test pins this.
  • Assign paths: branch records assignment failures as warnings, so a stalled assign body gets the new message but no timeout code. The note's --json claim holds for reads that abort the command.

Smaller test gaps from the review: the /myself read in Jira assign, some path arguments to the failure helpers, { cause }, and token absence in the new tests have no assertion of their own.

The 15s fetch signal also bounds reading the body, so a body that stalled
after the headers rejected with a TimeoutError that only the fetch call
translated. It missed TIMEOUT_MESSAGE and came out with code `failed`.

Linear, GitHub and Jira now translate it at every body read, `.text()` on
error responses included. A real parse failure behaves as before.

Closes #176

@baldurs-reviewer baldurs-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code-reviewer: minor issues

The change wraps every response-body read in the Linear, GitHub and Jira clients so that a TimeoutError raised while reading the body becomes the same did not answer within 15s error as a stalled fetch. Genuine parse failures are still passed through unchanged. The implementation is correct and consistent across the three clients, and the tests pin both the timeout and non-timeout paths for each. I found only two small points: one Linear test sits in the wrong describe, and the changeset's --json claim reaches further than the code does.


Reviewed 9be4e40 for baldurpan · claude-opus-5-5 · 7 files · $0.56

Comment thread src/integrations/linear.test.ts Resolved
Comment thread .changeset/stalled-body-timeout.md Resolved
Narrow the release note's --json claim to the reads that end the command.

@baldurs-reviewer baldurs-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code-reviewer follow-up: looks good

Since the last review, the Linear stalled-body test has moved into the fetchLinearIssue block, two startLinearIssue stalled-body cases (read and move) have been added, and the release note now limits its --json claim. Both earlier comments are addressed and nothing new turned up in these changes.

Earlier comments


Reviewed 00f74c7 (changes since 9be4e40) for baldurpan · claude-opus-5-5 · 2 files · $0.14

@baldurpan
baldurpan merged commit 22f57f7 into main Nov 1, 2026
2 checks passed
@baldurpan
baldurpan deleted the 176-a-body-that-stalls-past-the-15s-timeout-is-not branch November 1, 2026 17:43
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.

A body that stalls past the 15s timeout is not reported as a timeout (Linear, GitHub, Jira)

1 participant