Skip to content

feat: use native fetch for GraphQL transport#211

Open
iamfj wants to merge 6 commits intonextfrom
docs/issue-207-native-fetch-design
Open

feat: use native fetch for GraphQL transport#211
iamfj wants to merge 6 commits intonextfrom
docs/issue-207-native-fetch-design

Conversation

@iamfj
Copy link
Copy Markdown
Member

@iamfj iamfj commented Apr 27, 2026

What does this PR do?

Replaces the SDK-backed GraphQL raw request transport with native Node 22 fetch while preserving the public GraphQLClient API and existing retry/error behavior.

Closes #207

Type of change

  • Bug fix
  • New feature
  • Refactor (no behavior change)
  • Documentation
  • Tests
  • Build / CI

Checklist

  • npm run check:ci passes (lint + format)
  • npx tsc --noEmit passes (type check)
  • npm test passes (unit tests)
  • New code has tests (happy path + primary error case)
  • Commit messages follow Conventional Commits

Testing

  • npm run check:ci
  • npx tsc --noEmit
  • npm test
  • npm run build

Notes for reviewers

  • GraphQLClient now uses native fetch directly; resolvers and @linear/sdk remain unchanged for later staged migration work.
  • HTTP 429/5xx, native fetch network failures, GraphQL errors, invalid JSON, and timeout/abort behavior are covered in tests/unit/client/graphql-client.test.ts.
  • graphql is now a direct pinned production dependency because print(document) is used at runtime.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c2c89edb54

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +71 to +73
} catch (_error: unknown) {
if (response.ok) throw new Error("Invalid JSON response");
return undefined;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve abort errors in successful response parsing

If the timeout aborts after fetch() resolves but during response.text(), parseJsonResponse() will reject with an abort error; this catch block rewrites that into Invalid JSON response whenever response.ok is true. That masks timeouts from isAbortAfterTimeout() in request(), so these slow/stalled 200 responses are reported as JSON errors and are no longer retried as timeout failures.

Useful? React with 👍 / 👎.

@iamfj iamfj force-pushed the docs/issue-207-native-fetch-design branch from c2c89ed to 63e4c3b Compare April 27, 2026 14:06
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 63e4c3b2f0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +71 to +73
} catch (_error: unknown) {
if (response.ok) throw new Error("Invalid JSON response");
return undefined;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve abort failures when parsing error responses

Do not swallow all parsing exceptions for non-2xx responses here: if the timeout abort fires after fetch() returns headers but during response.text(), this branch returns undefined and the caller rethrows an HTTP-status GraphQLTransportError instead of Request timed out. In that scenario, stalled 4xx responses are misreported as regular HTTP failures and skip timeout-based retry behavior.

Useful? React with 👍 / 👎.

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.

deps: replace SDK-backed GraphQL transport with native fetch

1 participant