Skip to content

fix(core): only attach .then and .catch onto a promise if it gets dehydrated - #9847

Merged
TkDodo merged 2 commits into
mainfrom
feature/no-promise-dehydrate
Nov 5, 2025
Merged

fix(core): only attach .then and .catch onto a promise if it gets dehydrated#9847
TkDodo merged 2 commits into
mainfrom
feature/no-promise-dehydrate

Conversation

@TkDodo

@TkDodoTkDodo commented Nov 5, 2025

Copy link
Copy Markdown
Collaborator

🎯 Changes

✅ 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
    • Fixed unhandled promise rejections when dehydrating pending queries during server-side rendering.

@TkDodo
TkDodo requested a review from EphemNovember 5, 2025 13:30
@changeset-bot

changeset-botBot commented Nov 5, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 033c868

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

This PR includes changesets to release 19 packages
NameType
@tanstack/query-corePatch
@tanstack/angular-query-experimentalPatch
@tanstack/query-async-storage-persisterPatch
@tanstack/query-broadcast-client-experimentalPatch
@tanstack/query-persist-client-corePatch
@tanstack/query-sync-storage-persisterPatch
@tanstack/react-queryPatch
@tanstack/solid-queryPatch
@tanstack/svelte-queryPatch
@tanstack/vue-queryPatch
@tanstack/angular-query-persist-clientPatch
@tanstack/react-query-persist-clientPatch
@tanstack/solid-query-persist-clientPatch
@tanstack/svelte-query-persist-clientPatch
@tanstack/react-query-devtoolsPatch
@tanstack/react-query-next-experimentalPatch
@tanstack/solid-query-devtoolsPatch
@tanstack/svelte-query-devtoolsPatch
@tanstack/vue-query-devtoolsPatch

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

@coderabbitai

coderabbitaiBot commented Nov 5, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Introduces a changeset documenting a patch fix for @tanstack/query-core that wraps promise chains in dehydration with a no-op catch handler to suppress unhandled rejections on pending queries.

Changes

Cohort / File(s)Summary
Changeset documentation
.changeset/little-berries-search.md
Adds patch release notes documenting the fix for unhandled rejections on dehydrated promises
Hydration promise handling
packages/query-core/src/hydration.ts
Refactors dehydration logic to wrap pending query promises in a dehydratePromise function with a local catch(noop) to suppress unhandled rejections while preserving correct result propagation

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12–15 minutes

  • Verify the dehydratePromise wrapper function correctly handles promise chains without introducing regressions
  • Confirm the no-op catch handler doesn't mask legitimate errors or alter promise resolution behavior
  • Check that dehydrated query results still propagate correctly through the cache

Possibly related PRs

Poem

🐰 A promise once scattered and wild,
Now wrapped with a catch, gentle and mild,
No rejections left crying at night,
The hydration flows smooth—what a sight!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Description check⚠️ WarningThe description uses the correct template structure but lacks actual content in the 'Changes' section and all checklist items remain unchecked, including the required changeset generation.Fill in the 'Changes' section with details about the fix and its motivation, and ensure checklist items (especially changeset generation) are properly completed and checked.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the main change: only attaching .then and .catch callbacks to promises during dehydration, which aligns with the refactoring in hydration.ts.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/no-promise-dehydrate

📜 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 a5fca0e and 033c868.

📒 Files selected for processing (2)
  • .changeset/little-berries-search.md (1 hunks)
  • packages/query-core/src/hydration.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: TkDodo
Repo: TanStack/query PR: 9612
File: packages/query-async-storage-persister/src/asyncThrottle.ts:0-0
Timestamp: 2025-09-02T17:57:33.184Z
Learning: When importing from tanstack/query-core in other TanStack Query packages like query-async-storage-persister, a workspace dependency "tanstack/query-core": "workspace:*" needs to be added to the package.json.
📚 Learning: 2025-11-02T22:52:33.071Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.

Applied to files:

  • packages/query-core/src/hydration.ts
📚 Learning: 2025-09-02T17:57:33.184Z
Learnt from: TkDodo
Repo: TanStack/query PR: 9612
File: packages/query-async-storage-persister/src/asyncThrottle.ts:0-0
Timestamp: 2025-09-02T17:57:33.184Z
Learning: When importing from tanstack/query-core in other TanStack Query packages like query-async-storage-persister, a workspace dependency "tanstack/query-core": "workspace:*" needs to be added to the package.json.

Applied to files:

  • .changeset/little-berries-search.md
🧬 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)
🔇 Additional comments (3)
packages/query-core/src/hydration.ts (2)

82-104: LGTM! Clean encapsulation of promise handling.

The dehydratePromise wrapper correctly:

  • Chains serialization via .then(serializeData)
  • Preserves error redaction logic with appropriate logging in development
  • Adds catch(noop) to suppress unhandled rejections while allowing the rejection to propagate to the query cache

This ensures promise handlers are only attached during dehydration, aligning with the PR objective.


116-118: LGTM! Correctly scoped promise dehydration.

The conditional application of dehydratePromise() only when query.state.status === 'pending' ensures promise handlers are attached only when needed, preventing unnecessary overhead and potential unhandled rejection warnings in non-dehydration scenarios.

.changeset/little-berries-search.md (1)

1-5: LGTM! Changeset correctly documents the fix.

The changeset appropriately declares a patch release for @tanstack/query-core with a description that matches the PR objective.


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

@nx-cloud

nx-cloudBot commented Nov 5, 2025

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 033c868

CommandStatusDurationResult
nx affected --targets=test:sherif,test:knip,tes...✅ Succeeded45sView ↗
nx run-many --target=build --exclude=examples/*...✅ Succeeded1sView ↗

☁️ Nx Cloud last updated this comment at 2025-11-05 15:32:51 UTC

@pkg-pr-new

pkg-pr-newBot commented Nov 5, 2025

Copy link
Copy Markdown
More templates

@tanstack/angular-query-experimental

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

@tanstack/eslint-plugin-query

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

@tanstack/query-async-storage-persister

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

@tanstack/query-broadcast-client-experimental

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

@tanstack/query-core

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

@tanstack/query-devtools

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

@tanstack/query-persist-client-core

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

@tanstack/query-sync-storage-persister

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

@tanstack/react-query

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

@tanstack/react-query-devtools

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

@tanstack/react-query-next-experimental

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

@tanstack/react-query-persist-client

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

@tanstack/solid-query

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

@tanstack/solid-query-devtools

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

@tanstack/solid-query-persist-client

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

@tanstack/svelte-query

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

@tanstack/svelte-query-devtools

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

@tanstack/svelte-query-persist-client

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

@tanstack/vue-query

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

@tanstack/vue-query-devtools

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

commit: 033c868

@github-actions

github-actionsBot commented Nov 5, 2025

Copy link
Copy Markdown
Contributor

Sizes for commit 033c868:

BranchBundle Size
Main
This PR

@codecov

codecovBot commented Nov 5, 2025

Copy link
Copy Markdown

Codecov Report

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

Additional details and impacted files

Impacted file tree graph

@@ Coverage Diff @@## main #9847 +/- ##
===========================================
+ Coverage 45.75% 59.79% +14.04% 
===========================================
Files 200 129 -71 Lines 8408 5624 -2784 Branches 1929 1525 -404 ===========================================
- Hits 3847 3363 -484 + Misses 4113 1956 -2157 + Partials 448 305 -143 
ComponentsCoverage Δ
@tanstack/angular-query-experimental93.85% <ø> (ø)
@tanstack/eslint-plugin-query∅ <ø> (∅)
@tanstack/query-async-storage-persister43.85% <ø> (ø)
@tanstack/query-broadcast-client-experimental24.39% <ø> (ø)
@tanstack/query-codemods∅ <ø> (∅)
@tanstack/query-core97.38% <100.00%> (+<0.01%)⬆️
@tanstack/query-devtools3.48% <ø> (ø)
@tanstack/query-persist-client-core80.00% <ø> (ø)
@tanstack/query-sync-storage-persister84.61% <ø> (ø)
@tanstack/query-test-utils∅ <ø> (∅)
@tanstack/react-query96.01% <ø> (ø)
@tanstack/react-query-devtools10.00% <ø> (ø)
@tanstack/react-query-next-experimental∅ <ø> (∅)
@tanstack/react-query-persist-client100.00% <ø> (ø)
@tanstack/solid-query77.81% <ø> (ø)
@tanstack/solid-query-devtools61.90% <ø> (ø)
@tanstack/solid-query-persist-client100.00% <ø> (ø)
@tanstack/svelte-query∅ <ø> (∅)
@tanstack/svelte-query-devtools∅ <ø> (∅)
@tanstack/svelte-query-persist-client∅ <ø> (∅)
@tanstack/vue-query71.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.

@TkDodo
TkDodo marked this pull request as ready for review November 5, 2025 15:30
Ensure .then and .catch are only attached to dehydrated promises.
@Svish

Svish commented Nov 5, 2025

Copy link
Copy Markdown
Contributor

@TkDodo Re request to try this out, I reverted our project to before I removed the cancellation token thing, and was able to get the same errors in the log. I then installed the preview-version from this PR, and as far as I can see, it seems there are no longer any errors in the log. So, from my point of view at least, this PR seems to fix the issue. 👍

@TkDodo
TkDodo merged commit b4cd121 into mainNov 5, 2025
9 checks passed
@TkDodo
TkDodo deleted the feature/no-promise-dehydrate branch November 5, 2025 15:44
@github-actionsgithub-actionsBot mentioned this pull request Nov 5, 2025
@coderabbitaicoderabbitaiBot mentioned this pull request Jan 27, 2026
5 tasks
Sign up for freeto 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

@TkDodo@Svish