Skip to content

Conversation

Ephem
Copy link
Collaborator

@Ephem Ephem commented Oct 13, 2025

🎯 Changes

This PR adds two .catch(noop) to handle previously unhandled promise rejection errors when dehydrating and hydrating promises, which happens when de/rehydrating pending queries.

The errors themselves are still propagated to the query client like before, this is just handling two extraneous promises we are not using the output of.

There are still other active bugs stemming from how we use query.fetch to set up a retryer. I took a stab at adding a new query.createRetryer method and use that instead, but turns out this was a bigger refactor so I wanted to get this quick fix out quickly before revisiting that.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Bug Fixes

    • Prevents unhandled promise rejections during de/rehydration of pending queries, improving app stability and clearer error handling in development.
  • Tests

    • Simplified hydration tests by removing temporary unhandled rejection listeners, reflecting the new safe handling behavior.
  • Chores

    • Patch release updates to reflect stability improvements and ensure consistent behavior across related query packages.

Copy link

changeset-bot bot commented Oct 13, 2025

🦋 Changeset detected

Latest commit: 6960735

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

This PR includes changesets to release 19 packages
Name Type
@tanstack/react-query Patch
@tanstack/query-core Patch
@tanstack/react-query-devtools Patch
@tanstack/react-query-next-experimental Patch
@tanstack/react-query-persist-client Patch
@tanstack/angular-query-experimental Patch
@tanstack/query-async-storage-persister Patch
@tanstack/query-broadcast-client-experimental Patch
@tanstack/query-persist-client-core Patch
@tanstack/query-sync-storage-persister Patch
@tanstack/solid-query Patch
@tanstack/svelte-query Patch
@tanstack/vue-query Patch
@tanstack/angular-query-persist-client Patch
@tanstack/solid-query-persist-client Patch
@tanstack/svelte-query-persist-client Patch
@tanstack/solid-query-devtools Patch
@tanstack/svelte-query-devtools Patch
@tanstack/vue-query-devtools 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

Copy link

nx-cloud bot commented Oct 13, 2025

View your CI Pipeline Execution ↗ for commit 6960735

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 3m 54s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1m 17s View ↗

☁️ Nx Cloud last updated this comment at 2025-10-13 18:08:34 UTC

Copy link
Contributor

coderabbitai bot commented Oct 13, 2025

Walkthrough

Adds a shared dehydration promise with redaction and a no-op catch to prevent unhandled rejections for pending queries, applies a no-op catch during rehydration fetches, updates imports, removes test listeners for unhandledRejection, and adds a changeset for patch bumps to @tanstack/react-query and @tanstack/query-core.

Changes

Cohort / File(s) Summary
De/rehydration promise handling
packages/query-core/src/hydration.ts
Introduces a shared dehydration promise with error redaction, logging in non-production, and a no-op catch; rehydration now attaches a no-op catch to pending fetch promises; imports noop.
Test cleanup
packages/react-query/src/__tests__/HydrationBoundary.test.tsx
Removes setup/teardown of temporary unhandledRejection listeners; tests no longer suppress unhandled rejections explicitly.
Release metadata
.changeset/tall-banks-drop.md
Adds patch changeset for @tanstack/react-query and @tanstack/query-core with note on avoiding unhandled rejections during de/rehydration.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant App
  participant QueryClient
  participant Serializer as Serializer/Dehydrate
  participant Redactor as Error Redactor
  participant Logger

  rect rgba(230,245,255,0.5)
  note over App,QueryClient: Dehydrate pending queries (changed)
  App->>QueryClient: dehydrate()
  QueryClient->>Serializer: serialize pending query
  Serializer->>Redactor: redact non-permitted errors
  Redactor-->>Serializer: redacted error/result
  Serializer-->>QueryClient: shared promise (with catch(noop))
  QueryClient-->>App: DehydratedState (refs shared promise)
  end

  Note right of Logger: In non-production, log redacted errors
Loading
sequenceDiagram
  autonumber
  participant App
  participant Hydration as HydrationBoundary
  participant QueryClient
  participant Fetch as Pending Fetch

  rect rgba(230,255,230,0.5)
  note over App,Hydration: Rehydrate pending queries (changed)
  App->>Hydration: useDehydratedState(DehydratedState)
  Hydration->>QueryClient: rehydrate()
  QueryClient->>Fetch: resume/trigger pending query fetch
  Fetch-->>QueryClient: Promise
  QueryClient->>Fetch: attach catch(noop) to avoid unhandled rejection
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • manudeli

Poem

I nibble bytes with whiskered care,
Catching promises mid-air.
No thumps of panic, no alarms—
Redacted errs in gentle arms.
Dehydrate, rehydrate—hop, no flop!
My queue is calm—hip, hop, hop. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly and concisely summarizes the primary change by referencing the fix for unhandled promise rejections during de/rehydration of pending queries, matching the core modifications in the pull request.
Description Check ✅ Passed The pull request description follows the required template with all major sections present and clearly describes the changes, includes a completed checklist, and details the release impact including a generated changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ee85d16 and 6960735.

📒 Files selected for processing (3)
  • .changeset/tall-banks-drop.md (1 hunks)
  • packages/query-core/src/hydration.ts (4 hunks)
  • packages/react-query/src/__tests__/HydrationBoundary.test.tsx (0 hunks)
💤 Files with no reviewable changes (1)
  • packages/react-query/src/tests/HydrationBoundary.test.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
packages/query-core/src/hydration.ts (2)
packages/query-core/src/query.ts (1)
  • promise (198-200)
packages/query-core/src/utils.ts (1)
  • noop (82-82)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Preview
  • GitHub Check: Test
🔇 Additional comments (6)
packages/query-core/src/hydration.ts (5)

2-2: LGTM: Import added for unhandled rejection handling.

The noop import is correctly added and will be used to prevent unhandled promise rejections while preserving error propagation to the query client.


82-94: LGTM: Error redaction logic correctly implemented.

The promise chain properly:

  • Uses optional chaining for query.promise (may be undefined)
  • Serializes successful results
  • Redacts errors when required while logging originals in non-production
  • Maintains rejection state by returning Promise.reject(...) in both branches

This preserves error propagation to the query client while enabling controlled error redaction.


96-100: LGTM: Unhandled rejection prevention correctly implemented.

The .catch(noop) pattern is the correct approach:

  • Consumes the rejection locally to prevent unhandled rejection warnings
  • Doesn't interfere with downstream error handling (promise still rejects)
  • Uses optional chaining since promise may be undefined

The explanatory comment clearly documents the intent.


113-113: LGTM: Shared promise correctly referenced.

Using the shared promise variable (with noop catch attached) in the return object is correct and ensures the dehydrated promise won't trigger unhandled rejections.


271-277: LGTM: Hydration side also protected from unhandled rejections.

The .catch(noop) on query.fetch() correctly prevents unhandled rejection warnings during rehydration while preserving error propagation through the query client's error handling.

This completes the fix for both dehydration and rehydration flows.

.changeset/tall-banks-drop.md (1)

1-6: LGTM: Changeset correctly documents the fix.

The changeset properly:

  • Marks both affected packages for patch bumps (appropriate for a bug fix)
  • Provides a clear description of the change
  • Follows standard changeset format

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.

Copy link

pkg-pr-new bot commented Oct 13, 2025

More templates

@tanstack/angular-query-experimental

npm i https://pkg.pr.new/@tanstack/angular-query-experimental@9752

@tanstack/eslint-plugin-query

npm i https://pkg.pr.new/@tanstack/eslint-plugin-query@9752

@tanstack/query-async-storage-persister

npm i https://pkg.pr.new/@tanstack/query-async-storage-persister@9752

@tanstack/query-broadcast-client-experimental

npm i https://pkg.pr.new/@tanstack/query-broadcast-client-experimental@9752

@tanstack/query-core

npm i https://pkg.pr.new/@tanstack/query-core@9752

@tanstack/query-devtools

npm i https://pkg.pr.new/@tanstack/query-devtools@9752

@tanstack/query-persist-client-core

npm i https://pkg.pr.new/@tanstack/query-persist-client-core@9752

@tanstack/query-sync-storage-persister

npm i https://pkg.pr.new/@tanstack/query-sync-storage-persister@9752

@tanstack/react-query

npm i https://pkg.pr.new/@tanstack/react-query@9752

@tanstack/react-query-devtools

npm i https://pkg.pr.new/@tanstack/react-query-devtools@9752

@tanstack/react-query-next-experimental

npm i https://pkg.pr.new/@tanstack/react-query-next-experimental@9752

@tanstack/react-query-persist-client

npm i https://pkg.pr.new/@tanstack/react-query-persist-client@9752

@tanstack/solid-query

npm i https://pkg.pr.new/@tanstack/solid-query@9752

@tanstack/solid-query-devtools

npm i https://pkg.pr.new/@tanstack/solid-query-devtools@9752

@tanstack/solid-query-persist-client

npm i https://pkg.pr.new/@tanstack/solid-query-persist-client@9752

@tanstack/svelte-query

npm i https://pkg.pr.new/@tanstack/svelte-query@9752

@tanstack/svelte-query-devtools

npm i https://pkg.pr.new/@tanstack/svelte-query-devtools@9752

@tanstack/svelte-query-persist-client

npm i https://pkg.pr.new/@tanstack/svelte-query-persist-client@9752

@tanstack/vue-query

npm i https://pkg.pr.new/@tanstack/vue-query@9752

@tanstack/vue-query-devtools

npm i https://pkg.pr.new/@tanstack/vue-query-devtools@9752

commit: 6960735

Copy link

codecov bot commented Oct 13, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.78%. Comparing base (ee85d16) to head (6960735).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main    #9752       +/-   ##
===========================================
+ Coverage   45.53%   59.78%   +14.24%     
===========================================
  Files         196      125       -71     
  Lines        8327     5555     -2772     
  Branches     1894     1516      -378     
===========================================
- Hits         3792     3321      -471     
+ Misses       4093     1935     -2158     
+ Partials      442      299      -143     
Components Coverage Δ
@tanstack/angular-query-experimental 93.85% <ø> (ø)
@tanstack/eslint-plugin-query ∅ <ø> (∅)
@tanstack/query-async-storage-persister 43.85% <ø> (ø)
@tanstack/query-broadcast-client-experimental 24.39% <ø> (ø)
@tanstack/query-codemods ∅ <ø> (∅)
@tanstack/query-core 97.48% <100.00%> (+<0.01%) ⬆️
@tanstack/query-devtools 3.48% <ø> (ø)
@tanstack/query-persist-client-core 80.00% <ø> (ø)
@tanstack/query-sync-storage-persister 84.61% <ø> (ø)
@tanstack/query-test-utils ∅ <ø> (∅)
@tanstack/react-query 96.01% <ø> (ø)
@tanstack/react-query-devtools 10.00% <ø> (ø)
@tanstack/react-query-next-experimental ∅ <ø> (∅)
@tanstack/react-query-persist-client 100.00% <ø> (ø)
@tanstack/solid-query 78.06% <ø> (ø)
@tanstack/solid-query-devtools ∅ <ø> (∅)
@tanstack/solid-query-persist-client 100.00% <ø> (ø)
@tanstack/svelte-query ∅ <ø> (∅)
@tanstack/svelte-query-devtools ∅ <ø> (∅)
@tanstack/svelte-query-persist-client ∅ <ø> (∅)
@tanstack/vue-query 71.10% <ø> (ø)
@tanstack/vue-query-devtools ∅ <ø> (∅)
🚀 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.

@Ephem Ephem merged commit 4e1c433 into TanStack:main Oct 13, 2025
9 checks passed
@github-actions github-actions bot mentioned this pull request Oct 13, 2025
Hellol77 pushed a commit to Hellol77/query that referenced this pull request Oct 14, 2025
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.

2 participants