Skip to content

Commit 3fb30a9

Browse files
committed
fix(query-core): improve observer remount handling with signal consumption
1 parent 43ef2a8 commit 3fb30a9

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

packages/query-core/src/__tests__/query.test.tsx

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,8 +1196,7 @@ describe('query', () => {
11961196
test('should not override fetching state when revert happens after new observer subscribes', async () => {
11971197
const key = queryKey()
11981198

1199-
// @ts-expect-error This field has been added for troubleshooting purposes. Disable ts error for testing.
1200-
const queryFn = vi.fn(async ({ signal }) => {
1199+
const queryFn = vi.fn(async ({ signal: _signal }) => {
12011200
await sleep(50)
12021201
return 'data'
12031202
})
@@ -1236,4 +1235,47 @@ describe('query', () => {
12361235

12371236
expect(query.state.fetchStatus).toBe('fetching')
12381237
})
1238+
1239+
test('should throw CancelledError when revert happens with no data after observer removal', async () => {
1240+
const key = queryKey()
1241+
1242+
const queryFn = vi.fn(async ({ signal: _signal }) => {
1243+
await sleep(50)
1244+
return 'data'
1245+
})
1246+
1247+
const query = new Query({
1248+
client: queryClient,
1249+
queryKey: key,
1250+
queryHash: hashQueryKeyByOptions(key),
1251+
options: { queryFn },
1252+
})
1253+
1254+
const observer1 = new QueryObserver(queryClient, {
1255+
queryKey: key,
1256+
queryFn,
1257+
})
1258+
1259+
query.addObserver(observer1)
1260+
const promise1 = query.fetch()
1261+
1262+
await vi.advanceTimersByTimeAsync(5)
1263+
1264+
query.removeObserver(observer1)
1265+
1266+
const observer2 = new QueryObserver(queryClient, {
1267+
queryKey: key,
1268+
queryFn,
1269+
})
1270+
1271+
query.addObserver(observer2)
1272+
query.fetch()
1273+
1274+
await expect(promise1).rejects.toThrow(CancelledError)
1275+
1276+
expect(query.state.fetchStatus).toBe('fetching')
1277+
1278+
await vi.advanceTimersByTimeAsync(50)
1279+
expect(query.state.data).toBe('data')
1280+
})
12391281
})

packages/query-core/src/query.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ export class Query<
553553
// so we hatch onto that promise
554554
return this.#retryer.promise
555555
} else if (error.revert) {
556-
if (error.isObserverRemoval && this.observers.length > 0) {
556+
if (error.isObserverRemoval && this.isActive()) {
557557
if (this.state.data === undefined) {
558558
throw error
559559
}

0 commit comments

Comments
 (0)