Skip to content

test: Fix socket hang up in node-fetch 3.3.2 fails tests#10443

Merged
mtrezza merged 1 commit intoparse-community:alphafrom
mtrezza:test/fix-failing-node-related-tests
Apr 17, 2026
Merged

test: Fix socket hang up in node-fetch 3.3.2 fails tests#10443
mtrezza merged 1 commit intoparse-community:alphafrom
mtrezza:test/fix-failing-node-related-tests

Conversation

@mtrezza
Copy link
Copy Markdown
Member

@mtrezza mtrezza commented Apr 17, 2026

Pull Request

Issue

After bumping node-fetch from 3.2.10 to 3.3.2, GraphQL tests intermittently fail with socket hang up errors, for example:

ApolloError: request to http://localhost:13377/graphql failed, reason: socket hang up

Approach

node-fetch 3.2.10 automatically set Connection: close on every request. Version 3.3.2 removed that header (node-fetch/node-fetch#1736), deferring to Node.js defaults. On Node.js 19+, the default HTTP agent has keepAlive: true, so TCP connections persist in the agent's pool. When tests tear down and recreate the HTTP server on the same port between specs, stale pooled sockets get reused against the dead server, causing socket hang up.

The fix passes new http.Agent({ keepAlive: false }) in the lazy fetch wrapper used by the three affected test files, restoring close-after-response behavior.

Tasks

  • Add tests
  • Add changes to documentation (guides, repository pages, code comments)
  • Add security check
  • Add new Parse Error codes to Parse JS SDK

Summary by CodeRabbit

  • Tests
    • Updated HTTP connection management in test helpers to standardize request handling across test suites.

@parse-github-assistant
Copy link
Copy Markdown

parse-github-assistant bot commented Apr 17, 2026

🚀 Thanks for opening this pull request! We appreciate your effort in improving the project. Please let us know once your pull request is ready for review.

Tip

  • Keep pull requests small. Large PRs will be rejected. Break complex features into smaller, incremental PRs.
  • Use Test Driven Development. Write failing tests before implementing functionality. Ensure tests pass.
  • Group code into logical blocks. Add a short comment before each block to explain its purpose.
  • We offer conceptual guidance. Coding is up to you. PRs must be merge-ready for human review.
  • Our review focuses on concept, not quality. PRs with code issues will be rejected. Use an AI agent.
  • Human review time is precious. Avoid review ping-pong. Inspect and test your AI-generated code.

Note

Please respond to review comments from AI agents just like you would to comments from a human reviewer. Let the reviewer resolve their own comments, unless they have reviewed and accepted your commit, or agreed with your explanation for why the feedback was incorrect.

Caution

Pull requests must be written using an AI agent with human supervision. Pull requests written entirely by a human will likely be rejected, because of lower code quality, higher review effort and the higher risk of introducing bugs. Please note that AI review comments on this pull request alone do not satisfy this requirement. Our CI and AI review are safeguards, not development tools. If many issues are flagged, rethink your development approach. Invest more effort in planning and design rather than using review cycles to fix low-quality code.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 17, 2026

📝 Walkthrough

Walkthrough

Three test specification files were updated to inject custom HTTP agent configuration into their local fetch helper functions. The changes ensure all HTTP requests made during testing are configured with keepAlive: false by destructuring arguments, defaulting options, and merging agent settings.

Changes

Cohort / File(s) Summary
Test Fetch Helper Configuration
spec/GraphQLQueryComplexity.spec.js, spec/ParseGraphQLServer.spec.js, spec/vulnerabilities.spec.js
Updated local fetch helpers to inject custom http.Agent({ keepAlive: false }) into all fetch requests by destructuring arguments, defaulting options, and merging agent configuration.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Security Check ⚠️ Warning Object spread ordering vulnerability allows options.agent to override the enforced non-keepalive agent setting, bypassing security controls. Change spread order from {agent: new http.Agent({keepAlive: false}), ...options} to {...options, agent: new http.Agent({keepAlive: false})} to enforce the agent setting.
Engage In Review Feedback ⚠️ Warning Security issue identified in review feedback regarding agent configuration override vulnerability across three spec files remains unaddressed without reviewer engagement. Implement the proposed fix reordering spread operators or engage reviewer with discussion explaining current implementation acceptability.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description includes all required template sections with substantive content: Issue clearly explains the socket hang up problem after node-fetch upgrade, Approach details the root cause and solution, and Tasks section is appropriately completed.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The PR title begins with 'test:' prefix which is required and clearly describes the main change: fixing socket hang-up issues in node-fetch 3.3.2 that were causing test failures.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mtrezza mtrezza changed the title test: Fix failing node related tests fix: Socket hang up in node-fetch 3.3.2 fails tests Apr 17, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
spec/vulnerabilities.spec.js (1)

3-7: Enforce the no-keepalive agent and avoid creating a new Agent per call.

Line 6 currently lets options.agent override your no-keepalive setting (...options is last), and it allocates a fresh http.Agent on every request. Reuse one agent and place it last in the merge so the intent is guaranteed.

♻️ Proposed refactor
+const noKeepAliveAgent = new http.Agent({ keepAlive: false });
 const fetch = (...args) =>
-  import('node-fetch').then(({ default: fetch }) => {
+  import('node-fetch').then(({ default: nodeFetch }) => {
     const [url, options = {}] = args;
-    return fetch(url, { agent: new http.Agent({ keepAlive: false }), ...options });
+    return nodeFetch(url, { ...options, agent: noKeepAliveAgent });
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@spec/vulnerabilities.spec.js` around lines 3 - 7, The custom fetch wrapper
creates a new http.Agent on every call and allows options.agent to override the
no-keepalive intent; instead, create and reuse a single Agent instance (e.g.,
const noKeepAliveAgent = new http.Agent({ keepAlive: false })) and when merging
arguments ensure this agent is applied last so it cannot be overridden (use
mergedOptions = { ...options, agent: noKeepAliveAgent } or equivalent) in the
fetch implementation (identify the fetch wrapper, the http.Agent creation, and
options.agent usage to update).
spec/GraphQLQueryComplexity.spec.js (1)

5-9: Same fetch helper hardening: prevent agent override and reuse one Agent instance.

Line 8 has the same override/order issue and per-request Agent allocation. Apply the same pattern here for consistency and deterministic no-keepalive behavior.

♻️ Proposed refactor
+const noKeepAliveAgent = new http.Agent({ keepAlive: false });
 const fetch = (...args) =>
-  import('node-fetch').then(({ default: fetch }) => {
+  import('node-fetch').then(({ default: nodeFetch }) => {
     const [url, options = {}] = args;
-    return fetch(url, { agent: new http.Agent({ keepAlive: false }), ...options });
+    return nodeFetch(url, { ...options, agent: noKeepAliveAgent });
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@spec/GraphQLQueryComplexity.spec.js` around lines 5 - 9, The fetch helper
currently creates a new http.Agent per call and allows callers to override the
agent; change the implementation of the fetch helper (the fetch const) so it
creates a single shared agent instance (e.g., const sharedAgent = new
http.Agent({ keepAlive: false }) declared once outside the returned function)
and when merging options ensure the agent cannot be overridden by incoming
options (apply the incoming options after setting agent but omit any incoming
agent key or explicitly set agent: sharedAgent), preserving deterministic
no-keepalive behavior and avoiding per-request Agent allocation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@spec/ParseGraphQLServer.spec.js`:
- Around line 4-8: The inline fetch shim in the spec allows options.agent to
override the forced non-keepalive agent; update the merge so the created Agent
with keepAlive: false cannot be replaced (e.g., apply options first and then set
agent, or explicitly set agent = options.agent ?? new http.Agent({ keepAlive:
false }) before calling fetch). Modify the fetch helper in
ParseGraphQLServer.spec.js (the top-level fetch arrow function) so the final
options passed to the real fetch always have an agent with keepAlive: false.

---

Nitpick comments:
In `@spec/GraphQLQueryComplexity.spec.js`:
- Around line 5-9: The fetch helper currently creates a new http.Agent per call
and allows callers to override the agent; change the implementation of the fetch
helper (the fetch const) so it creates a single shared agent instance (e.g.,
const sharedAgent = new http.Agent({ keepAlive: false }) declared once outside
the returned function) and when merging options ensure the agent cannot be
overridden by incoming options (apply the incoming options after setting agent
but omit any incoming agent key or explicitly set agent: sharedAgent),
preserving deterministic no-keepalive behavior and avoiding per-request Agent
allocation.

In `@spec/vulnerabilities.spec.js`:
- Around line 3-7: The custom fetch wrapper creates a new http.Agent on every
call and allows options.agent to override the no-keepalive intent; instead,
create and reuse a single Agent instance (e.g., const noKeepAliveAgent = new
http.Agent({ keepAlive: false })) and when merging arguments ensure this agent
is applied last so it cannot be overridden (use mergedOptions = { ...options,
agent: noKeepAliveAgent } or equivalent) in the fetch implementation (identify
the fetch wrapper, the http.Agent creation, and options.agent usage to update).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 39cab0b1-b102-4261-b57e-11cfda3c3b2e

📥 Commits

Reviewing files that changed from the base of the PR and between f303f75 and caf05dd.

📒 Files selected for processing (3)
  • spec/GraphQLQueryComplexity.spec.js
  • spec/ParseGraphQLServer.spec.js
  • spec/vulnerabilities.spec.js

Comment thread spec/ParseGraphQLServer.spec.js
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.51%. Comparing base (f303f75) to head (caf05dd).
⚠️ Report is 3 commits behind head on alpha.

Additional details and impacted files
@@            Coverage Diff             @@
##            alpha   #10443      +/-   ##
==========================================
+ Coverage   92.09%   92.51%   +0.41%     
==========================================
  Files         192      192              
  Lines       16792    16792              
  Branches      234      234              
==========================================
+ Hits        15465    15535      +70     
+ Misses       1300     1234      -66     
+ Partials       27       23       -4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mtrezza mtrezza changed the title fix: Socket hang up in node-fetch 3.3.2 fails tests test: Fix socket hang up in node-fetch 3.3.2 fails tests Apr 17, 2026
@mtrezza mtrezza merged commit fc53270 into parse-community:alpha Apr 17, 2026
24 checks passed
@parseplatformorg
Copy link
Copy Markdown
Contributor

🎉 This change has been released in version 9.9.0-alpha.1

@parseplatformorg parseplatformorg added the state:released-alpha Released as alpha version label Apr 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state:released-alpha Released as alpha version

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants