Skip to content

Commit b4cd121

Browse files
authored
fix(core): only attach .then and .catch onto a promise if it gets dehydrated (#9847)
* fix(core): only attach .then and .catch onto a promise if it gets dehydrated * Fix promise handling in core for dehydrated states Ensure .then and .catch are only attached to dehydrated promises.
1 parent a5fca0e commit b4cd121

File tree

2 files changed

+28
-19
lines changed

2 files changed

+28
-19
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@tanstack/query-core": patch
3+
---
4+
5+
fix(core): only attach .then and .catch onto a promise if it gets dehydrated

packages/query-core/src/hydration.ts

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -79,25 +79,29 @@ function dehydrateQuery(
7979
serializeData: TransformerFn,
8080
shouldRedactErrors: (error: unknown) => boolean,
8181
): DehydratedQuery {
82-
const promise = query.promise?.then(serializeData).catch((error) => {
83-
if (!shouldRedactErrors(error)) {
84-
// Reject original error if it should not be redacted
85-
return Promise.reject(error)
86-
}
87-
// If not in production, log original error before rejecting redacted error
88-
if (process.env.NODE_ENV !== 'production') {
89-
console.error(
90-
`A query that was dehydrated as pending ended up rejecting. [${query.queryHash}]: ${error}; The error will be redacted in production builds`,
91-
)
92-
}
93-
return Promise.reject(new Error('redacted'))
94-
})
82+
const dehydratePromise = () => {
83+
const promise = query.promise?.then(serializeData).catch((error) => {
84+
if (!shouldRedactErrors(error)) {
85+
// Reject original error if it should not be redacted
86+
return Promise.reject(error)
87+
}
88+
// If not in production, log original error before rejecting redacted error
89+
if (process.env.NODE_ENV !== 'production') {
90+
console.error(
91+
`A query that was dehydrated as pending ended up rejecting. [${query.queryHash}]: ${error}; The error will be redacted in production builds`,
92+
)
93+
}
94+
return Promise.reject(new Error('redacted'))
95+
})
96+
97+
// Avoid unhandled promise rejections
98+
// We need the promise we dehydrate to reject to get the correct result into
99+
// the query cache, but we also want to avoid unhandled promise rejections
100+
// in whatever environment the prefetches are happening in.
101+
promise?.catch(noop)
95102

96-
// Avoid unhandled promise rejections
97-
// We need the promise we dehydrate to reject to get the correct result into
98-
// the query cache, but we also want to avoid unhandled promise rejections
99-
// in whatever environment the prefetches are happening in.
100-
promise?.catch(noop)
103+
return promise
104+
}
101105

102106
return {
103107
dehydratedAt: Date.now(),
@@ -110,7 +114,7 @@ function dehydrateQuery(
110114
queryKey: query.queryKey,
111115
queryHash: query.queryHash,
112116
...(query.state.status === 'pending' && {
113-
promise,
117+
promise: dehydratePromise(),
114118
}),
115119
...(query.meta && { meta: query.meta }),
116120
}

0 commit comments

Comments
 (0)