Errors don't propagate to new on-demand live queries after an earlier request succeeds
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 68/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- typescript
- 領域
- data
調査の方向性
queryCollectionOptions と createLiveQueryCollection を通じて公開されているオンデマンド動作から始め、この issue における再現手順と、期待されるステータスと実際のステータスを使用してください。後続のフィルタリングされたリクエストが live query のエラー状態にどのような影響を与えるかを確認し、その後、失敗したクエリがエラーを報告する一方で、成功したクエリは ready のままであることを確認してください。
索引モデルが issue の本文から書いたものです。
説明
- [x ] I've validated the bug against the latest version of DB packages
Describe the bug
The initial error-propagation issue in #1260 (https://github.com/TanStack/db/issues/1260) was recently resolved. While testing that fix with syncMode: 'on-demand', I found a further problem with that implementation.
After one filtered request succeeds, subsequent live queries that request different subsets do not enter the error state when their requests fail. This is a common use case for on-demand collections—for example, fetching different date ranges or ID ranges.
I would expect an error from a later filtered request to propagate to that specific live query, while existing live queries with usable data remain ready.
Tested with
- @tanstack/db: 0.8.3
- @tanstack/query-core: 5.102.2
- @tanstack/query-db-collection: 1.2.8
To Reproduce
import { QueryClient } from '@tanstack/query-core';
import { createCollection, createLiveQueryCollection, eq, parseLoadSubsetOptions } from '@tanstack/db';
import { queryCollectionOptions } from '@tanstack/query-db-collection';
const successfulTodoId = 'successful';
const failingTodoId = 'failing';
const requestedTodoIds = [];
let resolveSuccessfulTodoRequest;
const successfulTodoRequestFinished = new Promise((resolve) => {
resolveSuccessfulTodoRequest = resolve;
});
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
},
});
const todoCollection = createCollection(
queryCollectionOptions({
queryKey: ['todos'],
queryClient,
retry: false,
syncMode: 'on-demand',
queryFn: async (context) => {
const requestedTodoId = parseLoadSubsetOptions(context.meta?.loadSubsetOptions).filters.find(
({ operator }) => operator === 'eq',
)?.value;
requestedTodoIds.push(String(requestedTodoId));
if (requestedTodoId === successfulTodoId) {
const result = [{ id: successfulTodoId, completed: false, text: 'Successful todo' }];
resolveSuccessfulTodoRequest();
return result;
}
if (requestedTodoId === failingTodoId) {
throw new Error('Failed to fetch filtered todos');
}
return [];
},
getKey: (todo) => todo.id,
}),
);
const successfulTodoQuery = createLiveQueryCollection({
query: (q) => q.from({ todo: todoCollection }).where(({ todo }) => eq(todo.id, successfulTodoId)),
startSync: true,
});
// Wait until the first live query and its backend request have completed.
await successfulTodoQuery.preload();
await successfulTodoRequestFinished;
if (JSON.stringify(requestedTodoIds) !== JSON.stringify([successfulTodoId])) {
throw new Error(`The successful query did not finish before the failing query started:
${JSON.stringify(requestedTodoIds)}`);
}
const failingTodoQuery = createLiveQueryCollection({
query: (q) => q.from({ todo: todoCollection }).where(({ todo }) => eq(todo.id, failingTodoId)),
startSync: true,
});
await failingTodoQuery.preload().catch(() => undefined);
console.log({
requestedTodoIds,
todoCollectionReady: todoCollection.isReady(),
todoCollectionHasError: todoCollection.utils.isError,
todoCollectionLastError: todoCollection.utils.lastError?.message,
successfulTodoQueryStatus: successfulTodoQuery.status,
failingTodoQueryStatus: failingTodoQuery.status,
});
Expected behavior
Expected output:
{
requestedTodoIds: ['successful', 'failing'],
todoCollectionReady: true,
todoCollectionHasError: true,
todoCollectionLastError: 'Failed to fetch filtered todos',
successfulTodoQueryStatus: 'ready',
failingTodoQueryStatus: 'error',
}
Actual output:
{
requestedTodoIds: ['successful', 'failing'],
todoCollectionReady: true,
todoCollectionHasError: true,
todoCollectionLastError: 'Failed to fetch filtered todos',
successfulTodoQueryStatus: 'ready',
failingTodoQueryStatus: 'ready',
}
- 主要言語
- TypeScript
- スター
- 3.9k
- フォーク
- 268
- 平均マージ
- 1日 1時間
- マージ済み PR(30日)
- 212
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
TanStack/db のほかの issue
-
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
electric-db-collection: on-demand + persistence fails after relaunch with "Snapshot requests are not supported in full mode"対応中かも @KyleAMathews が 2 日前に担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 68/100
TanStack/db#2056 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 45/100
メンテナーはふだん 1 日以内に返信
似ている issue
-
[Bug] The clients language filter cannot select the rows the page labels as unknown対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
apache/rocketmq-dashboard#6103 ·
メンテナーはふだん 4 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
cockpit-project/cockpit-machines#2835 ·
メンテナーはふだん 2 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
cloudflare/kumo#866 ·
メンテナーはふだん 1 日以内に返信
-
area:connector bug
難易度 1/5 1時間未満 初心者へのやさしさ 82/100
メンテナーはふだん 1 日以内に返信
-
autoInject recall silently drops memory injection on long / non-Latin prompts (HTTP 400 Query too long)対応中かも @Epsilon006 が今日担当しました。 オープンintegration:coding-agents
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
vectorize-io/hindsight#5476 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信