Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Errors don't propagate to new on-demand live queries after an earlier request succeeds

クローズ
#1,764 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 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

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

TanStack/db のほかの issue

TanStack/db の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。