Skip to content

Conversation

@brenelz
Copy link
Contributor

@brenelz brenelz commented Nov 3, 2025

🎯 Changes

When doing something like this in tanstack router for solid we get an error that the query can not be undefined. It seems like it should allow it to be undefined and even skip the error if its a redirect.

I'm not 100% this is the right fix but at least its a start.

const redirectFn = useServerFn($redirectServerFn)
  const query = useQuery(() => ({
    queryKey: ['redirect-test-ssr'],
    queryFn: () => redirectFn(),
  }))

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Improved error handling to skip errors when returned data is undefined, enhancing server-side rendering stability and data synchronization reliability.

@changeset-bot
Copy link

changeset-bot bot commented Nov 3, 2025

🦋 Changeset detected

Latest commit: a6069f5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@tanstack/solid-query Patch
@tanstack/solid-query-devtools Patch
@tanstack/solid-query-persist-client Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@nx-cloud
Copy link

nx-cloud bot commented Nov 3, 2025

View your CI Pipeline Execution ↗ for commit a6069f5

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 2m 22s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1s View ↗

☁️ Nx Cloud last updated this comment at 2025-11-03 04:53:52 UTC

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 3, 2025

Walkthrough

Updates error handling logic in server-side subscription of useBaseQuery to require data presence before rejecting errors. Also adds a corresponding changelog entry documenting the patch bump and behavior change for @tanstack/solid-query.

Changes

Cohort / File(s) Summary
Changelog entry
\.changeset/green-lands-occur.md
New changelog documenting patch bump for @tanstack/solid-query and note to skip errors when returned data is undefined
Server subscription error handling
packages/solid-query/src/useBaseQuery.ts
Modified error rejection condition to require both existing result.data and error in unwrappedResult; delays rejection unless data is present, otherwise resolves with hydrated result

Sequence Diagram(s)

sequenceDiagram
    participant Sub as Server Subscription
    participant Handler as Error Handler
    participant Result as Result State

    Note over Sub,Result: Error handling comparison

    rect rgb(200, 220, 255)
    Note over Handler: OLD: Any error → reject
    Sub->>Handler: unwrappedResult has error
    Handler->>Result: Reject immediately
    end

    rect rgb(220, 255, 220)
    Note over Handler: NEW: Requires result.data
    Sub->>Handler: Check if result.data exists
    alt data exists
        Handler->>Result: Reject with error
    else data undefined
        Handler->>Result: Resolve with hydrated result
    end
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • Core logic change is focused and localized to a single conditional, but affects server hydration error path which warrants careful attention
  • Review should verify the new condition correctly handles edge cases where data is undefined but an error exists
  • Changelog entry is straightforward; primary focus should be on testing scenarios for the server subscription behavior

Poem

🐰 When hydration flows and errors arise,
We check for data before surprise,
If present, reject with grace,
If absent, hydration takes place! ✨

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "fix(solid-query): ignore error if data undefined so can redirect" directly summarizes the main change in the pull request. The core modification in useBaseQuery.ts alters the error handling logic to delay rejection unless result.data is defined, which is precisely what the title describes: ignoring errors when data is undefined to enable redirect functionality. The title is concise, specific to the solid-query package, and clearly communicates the primary intent of the changeset without unnecessary noise or vague terminology.
Description Check ✅ Passed The PR description follows the required template with all major sections present and completed. The "🎯 Changes" section explains the context (tanstack router redirect scenario) and provides a code example showing the use case, addressing both what changed and why. The "✅ Checklist" section confirms the author followed contributing guidelines and tested locally, while the "🚀 Release Impact" section confirms a changeset was generated for this published code change. Although the author expresses uncertainty about whether this is the final solution, all required template sections are substantively filled out and the necessary information for review is provided.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 3, 2025

More templates

@tanstack/angular-query-experimental

npm i https://pkg.pr.new/@tanstack/angular-query-experimental@9841

@tanstack/eslint-plugin-query

npm i https://pkg.pr.new/@tanstack/eslint-plugin-query@9841

@tanstack/query-async-storage-persister

npm i https://pkg.pr.new/@tanstack/query-async-storage-persister@9841

@tanstack/query-broadcast-client-experimental

npm i https://pkg.pr.new/@tanstack/query-broadcast-client-experimental@9841

@tanstack/query-core

npm i https://pkg.pr.new/@tanstack/query-core@9841

@tanstack/query-devtools

npm i https://pkg.pr.new/@tanstack/query-devtools@9841

@tanstack/query-persist-client-core

npm i https://pkg.pr.new/@tanstack/query-persist-client-core@9841

@tanstack/query-sync-storage-persister

npm i https://pkg.pr.new/@tanstack/query-sync-storage-persister@9841

@tanstack/react-query

npm i https://pkg.pr.new/@tanstack/react-query@9841

@tanstack/react-query-devtools

npm i https://pkg.pr.new/@tanstack/react-query-devtools@9841

@tanstack/react-query-next-experimental

npm i https://pkg.pr.new/@tanstack/react-query-next-experimental@9841

@tanstack/react-query-persist-client

npm i https://pkg.pr.new/@tanstack/react-query-persist-client@9841

@tanstack/solid-query

npm i https://pkg.pr.new/@tanstack/solid-query@9841

@tanstack/solid-query-devtools

npm i https://pkg.pr.new/@tanstack/solid-query-devtools@9841

@tanstack/solid-query-persist-client

npm i https://pkg.pr.new/@tanstack/solid-query-persist-client@9841

@tanstack/svelte-query

npm i https://pkg.pr.new/@tanstack/svelte-query@9841

@tanstack/svelte-query-devtools

npm i https://pkg.pr.new/@tanstack/svelte-query-devtools@9841

@tanstack/svelte-query-persist-client

npm i https://pkg.pr.new/@tanstack/svelte-query-persist-client@9841

@tanstack/vue-query

npm i https://pkg.pr.new/@tanstack/vue-query@9841

@tanstack/vue-query-devtools

npm i https://pkg.pr.new/@tanstack/vue-query-devtools@9841

commit: a6069f5

@codecov
Copy link

codecov bot commented Nov 3, 2025

Codecov Report

❌ Patch coverage is 0% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 76.39%. Comparing base (38b4008) to head (a6069f5).
⚠️ Report is 16 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main    #9841       +/-   ##
===========================================
+ Coverage   45.74%   76.39%   +30.65%     
===========================================
  Files         200       19      -181     
  Lines        8404      394     -8010     
  Branches     1919       81     -1838     
===========================================
- Hits         3844      301     -3543     
+ Misses       4112       76     -4036     
+ Partials      448       17      -431     
Components Coverage Δ
@tanstack/angular-query-experimental ∅ <ø> (∅)
@tanstack/eslint-plugin-query ∅ <ø> (∅)
@tanstack/query-async-storage-persister ∅ <ø> (∅)
@tanstack/query-broadcast-client-experimental ∅ <ø> (∅)
@tanstack/query-codemods ∅ <ø> (∅)
@tanstack/query-core ∅ <ø> (∅)
@tanstack/query-devtools ∅ <ø> (∅)
@tanstack/query-persist-client-core ∅ <ø> (∅)
@tanstack/query-sync-storage-persister ∅ <ø> (∅)
@tanstack/query-test-utils ∅ <ø> (∅)
@tanstack/react-query ∅ <ø> (∅)
@tanstack/react-query-devtools ∅ <ø> (∅)
@tanstack/react-query-next-experimental ∅ <ø> (∅)
@tanstack/react-query-persist-client ∅ <ø> (∅)
@tanstack/solid-query 77.81% <0.00%> (-0.26%) ⬇️
@tanstack/solid-query-devtools 61.90% <ø> (ø)
@tanstack/solid-query-persist-client 100.00% <ø> (ø)
@tanstack/svelte-query ∅ <ø> (∅)
@tanstack/svelte-query-devtools ∅ <ø> (∅)
@tanstack/svelte-query-persist-client ∅ <ø> (∅)
@tanstack/vue-query ∅ <ø> (∅)
@tanstack/vue-query-devtools ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
.changeset/green-lands-occur.md (1)

1-5: Expand the changeset description to explain the behavioral change.

The current description is too brief for a behavioral change in error handling. Consider adding:

  • The specific use case (redirect scenarios with undefined data)
  • That this affects server-side hydration/SSR path
  • Potential implications (errors with undefined data won't reject during SSR)

Apply this diff to improve the description:

 ---
 '@tanstack/solid-query': patch
 ---
 
-Skip errors if returned data is undefined
+Skip errors during SSR when returned data is undefined. This allows redirect responses that return undefined to avoid triggering error rejection in server-side query hydration, enabling proper handling of redirects in frameworks like TanStack Router for Solid.
packages/solid-query/src/useBaseQuery.ts (1)

177-187: Consider documenting the asymmetry between server and client error handling.

The client subscriber (lines 177-187) has fundamentally different error handling than the server subscriber (lines 148-168):

  • Server: Uses promises with reject/resolve
  • Client: Updates state reactively without rejecting

While this asymmetry may be intentional due to SSR vs. client hydration differences, it would be helpful to document why they differ, especially since your change only affects the server path.

Consider adding a comment explaining the design:

  const createClientSubscriber = () => {
+   // Client-side errors are handled through reactive state updates
+   // rather than promise rejection, allowing the UI to respond
+   // to error states without throwing
    const obs = observer()
    return obs.subscribe((result) => {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 40b296b and a6069f5.

📒 Files selected for processing (2)
  • .changeset/green-lands-occur.md (1 hunks)
  • packages/solid-query/src/useBaseQuery.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Preview
  • GitHub Check: Test
🔇 Additional comments (2)
packages/solid-query/src/useBaseQuery.ts (2)

248-259: Inconsistent error handling between lifecycle phases confirmed.

The inconsistency you identified is real and significant. The code handles errors differently depending on when they occur:

  • Line 258 (initial effect): Rejects errors immediately if shouldThrowError() returns true, regardless of data state
  • Line 160 (subscription callback): Only rejects errors if result.data !== undefined

This creates unpredictable behavior: an error that occurs early might be rejected, but the same error arriving via subscription later could be swallowed if data is still undefined.

Recommended verification:

  1. Confirm whether errors should consistently consider data presence across both phases
  2. Test scenarios where errors occur during initial fetch vs. during refetch
  3. Determine if line 258 should also require observerResult.data !== undefined before rejecting

148-168: Verify whether error handling fallback at lines 248-259 adequately addresses the error masking concern and clarify redirect handling intent.

The concerns about error masking and asymmetry are partially valid. The code at line 159 does skip rejection when result.data === undefined && unwrappedResult.isError. However, there's a fallback error check at lines 248-259 that rejects if observerResult.isError && !observerResult.isFetching && !isRestoring() && shouldThrowError().

Key questions to clarify:

  1. Does the fallback catch masked errors? The fallback depends on state updates and timing — if errors during data === undefined update observerResult.isError, they'll eventually be caught. But this creates a race condition window where the promise resolves before the error is thrown.

  2. What is the redirect scenario? The logic assumes redirects result in data === undefined + isError === true. Is there explicit redirect detection, or is this a heuristic?

  3. Is asymmetry intentional? createServerSubscriber has data guard logic, but createClientSubscriber doesn't handle the promise — instead relying on the fallback. The design rationale isn't documented in comments.

Without understanding the redirect handling requirements, this appears to be either a legitimate workaround with undocumented assumptions or an incomplete error handling approach.

const unwrappedResult = hydratableObserverResult(query, result)

if (unwrappedResult.isError) {
if (result.data !== undefined && unwrappedResult.isError) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this only skips it for the server subscriber. I am not sure if there is a better heuristic here instead of just data is undefined

@birkskyum birkskyum merged commit d537d2b into TanStack:main Nov 3, 2025
8 of 9 checks passed
@github-actions github-actions bot mentioned this pull request Nov 3, 2025
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.

2 participants