Skip to content

fix(query-core): propagate AbortSignal reason in infiniteQueryBehavior fetchPage cancellation#10476

Open
kuishou68 wants to merge 1 commit intoTanStack:mainfrom
kuishou68:fix/10475-infinite-query-reject-with-abort-reason
Open

fix(query-core): propagate AbortSignal reason in infiniteQueryBehavior fetchPage cancellation#10476
kuishou68 wants to merge 1 commit intoTanStack:mainfrom
kuishou68:fix/10475-infinite-query-reject-with-abort-reason

Conversation

@kuishou68
Copy link
Copy Markdown

@kuishou68 kuishou68 commented Apr 13, 2026

Summary

Fixes #10475

Problem

In infiniteQueryBehavior.ts, the internal fetchPage helper function calls Promise.reject() without any argument when a query cancellation is detected via the cancelled flag (which is set by the AbortSignal abort event listener):

// Before (bug)
const fetchPage = async (data, param, previous) => {
  if (cancelled) {
    return Promise.reject()  // rejects with undefined!
  }
  // ...
}

When query.cancel()abortController.abort() is called, the abort signal fires and sets cancelled = true. On the next iteration of the multi-page fetch loop, fetchPage rejects with undefined instead of the proper AbortError that is set as context.signal.reason.

Fix

Propagate context.signal.reason as the rejection value, which is a DOMException with name "AbortError" when AbortController.abort() is called without an explicit reason (per the AbortSignal spec):

// After (fix)
const fetchPage = async (data, param, previous) => {
  if (cancelled) {
    return Promise.reject(context.signal.reason)  // proper AbortError DOMException
  }
  // ...
}

Impact

This fixes the following issues that occur when an infinite query is cancelled mid-pagination:

  • Custom retry functions receiving undefined instead of an AbortError
  • QueryCache.onError callbacks receiving undefined as the error argument
  • Error boundaries via throwOnError showing "undefined" errors

Testing

The fix is minimal and targeted. The change ensures that when the AbortSignal fires during a multi-page infinite query fetch, the proper DOMException{ name: "AbortError" } is propagated as the rejection reason, consistent with the Web AbortController specification.

Summary by CodeRabbit

  • Bug Fixes
    • Improved cancellation error handling to properly communicate cancellation reasons when operations are cancelled, enabling better error diagnostics and debugging.

…hPage (Closes TanStack#10475)

Signed-off-by: Cocoon-Break <54054995+kuishou68@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ec48e2f7-9a07-4160-a8db-8176e37d4a5d

📥 Commits

Reviewing files that changed from the base of the PR and between 4c489e4 and 2163c11.

📒 Files selected for processing (1)
  • packages/query-core/src/infiniteQueryBehavior.ts

📝 Walkthrough

Walkthrough

The fetchPage helper function in infiniteQueryBehavior.ts now rejects with the actual AbortSignal reason when a query is cancelled, instead of rejecting with an undefined value. This ensures proper error propagation to retry functions and error handlers.

Changes

Cohort / File(s) Summary
AbortSignal Reason Propagation
packages/query-core/src/infiniteQueryBehavior.ts
Modified cancellation behavior in fetchPage to reject with context.signal.reason instead of rejecting without an error value, ensuring proper error information flows to error handlers and retry logic.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Poem

🐰 A promise once rejected bare,
Now carries reason through the air,
No more undefined shall flow,
The AbortSignal's truth we'll know! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description provides comprehensive context including problem statement, fix explanation, and impact analysis. However, it does not include the required checklist items from the template. Complete the checklist by confirming local testing with 'pnpm run test:pr' and indicate whether a changeset was generated as required by the template.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: propagating AbortSignal reason in infiniteQueryBehavior fetchPage cancellation, which directly matches the single-line code change in the PR.
Linked Issues check ✅ Passed The code change directly addresses issue #10475 by replacing Promise.reject() with Promise.reject(context.signal.reason), ensuring proper AbortError propagation to retry functions, onError callbacks, and error boundaries.
Out of Scope Changes check ✅ Passed The change is narrowly scoped to the specific bug: only modifying the cancellation rejection in fetchPage from Promise.reject() to Promise.reject(context.signal.reason), with no other modifications to control flow or exports.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Sign up for free to 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.

bug: infiniteQueryBehavior fetchPage rejects with undefined when cancelled instead of propagating AbortSignal reason

1 participant