router icon indicating copy to clipboard operation
router copied to clipboard

fix(router-core): handle AbortError in router execution flow

Open leesb971204 opened this issue 6 months ago • 12 comments

fixes #4517

Summary by CodeRabbit

  • Bug Fixes

    • Prevents error screens when a loader is aborted (AbortError). The app now continues rendering the intended content, applies head updates, and respects base paths on initial load.
    • Reduces unnecessary error flashes during canceled navigations.
  • Tests

    • Added tests validating AbortError handling on initial load with a base path for React and Solid routers.
    • Minor test update adjusting className order to stabilize assertions.

leesb971204 avatar Jul 03 '25 05:07 leesb971204

🤖 Nx Cloud AI Fix Eligible

An automatically generated fix could have helped fix failing tasks for this run, but Self-healing CI is disabled for this workspace. Visit workspace settings to enable it and get automatic fixes in future runs.

To disable these notifications, a workspace admin can disable them in workspace settings.


View your CI Pipeline Execution ↗ for commit 4f872078a6dcc280eaea31e28fbf42f184b076f6

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ❌ Failed 9m 10s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1m 44s View ↗

☁️ Nx Cloud last updated this comment at 2025-12-23 14:32:15 UTC

nx-cloud[bot] avatar Jul 03 '25 05:07 nx-cloud[bot]

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@4570
@tanstack/directive-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@4570
@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@4570
@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@4570
@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@4570
@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@4570
@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@4570
@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@4570
@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@4570
@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@4570
@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@4570
@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@4570
@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@4570
@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@4570
@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@4570
@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@4570
@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@4570
@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@4570
@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@4570
@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@4570
@tanstack/server-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@4570
@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@4570
@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@4570
@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@4570
@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@4570
@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@4570
@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@4570
@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@4570
@tanstack/start-fn-stubs

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-fn-stubs@4570
@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@4570
@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@4570
@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@4570
@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@4570
@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@4570
@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@4570
@tanstack/vue-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router@4570
@tanstack/vue-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-devtools@4570
@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-ssr-query@4570
@tanstack/vue-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start@4570
@tanstack/vue-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-client@4570
@tanstack/vue-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-server@4570
@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@4570

commit: 4f87207

pkg-pr-new[bot] avatar Jul 03 '25 05:07 pkg-pr-new[bot]

@SeanCassiere

Would there be a chance for us to have a conversation about this?

leesb971204 avatar Jul 14 '25 00:07 leesb971204

Sorry about that!

@schiller-manuel there were recent changes this flow if I'm not mistaken with the selective SSR stuff. Would this be an issue?

@leesb971204 provided Manuel's fine with these changes, I don't see a reason not to get this pushed in.

Edit: Also, please make sure that your test are reflected in @tanstack/solid-router as well.

Thanks for the comment! I’ve added the same test to solid-router as well.

leesb971204 avatar Jul 14 '25 01:07 leesb971204

Sorry about that!

@schiller-manuel there were recent changes this flow if I'm not mistaken with the selective SSR stuff. Would this be an issue?

@leesb971204 provided Manuel's fine with these changes, I don't see a reason not to get this pushed in.

Edit: Also, please make sure that your test are reflected in @tanstack/solid-router as well.

Are there any other tasks that need to be completed before this work can be approved?

leesb971204 avatar Jul 21 '25 00:07 leesb971204

Are there any other tasks that need to be completed before this work can be approved?

Other than the current merge conflict, as mentioned here, I'd like @schiller-manuel to take a look at how this is being handled.

SeanCassiere avatar Jul 21 '25 22:07 SeanCassiere

Is there any particular reason this work hasn’t been reviewed yet?

leesb971204 avatar Aug 12 '25 06:08 leesb971204

no, we are just busy with a lot of stuff, sorry. will get back to you as soon as time permits

schiller-manuel avatar Aug 12 '25 17:08 schiller-manuel

Walkthrough

Adds AbortError handling in loader error flow to prevent error propagation on initial load with basepath. Executes head, preserves/updates match status, and returns early. Adds React and Solid tests reproducing AbortError during basepath mount and asserting no error UI and correct path.

Changes

Cohort / File(s) Summary
Core loader error handling
packages/router-core/src/load-matches.ts
Intercepts DOMException with name "AbortError" during loader errors; runs executeHead, merges head result, preserves prior pending status as success, and exits without triggering error handling.
React tests for AbortError + basepath
packages/react-router/tests/loaders.test.tsx
Adds test for loader rejecting with AbortError on initial load with basepath; asserts index renders, error UI absent, and path includes basepath. Minor className order change in a reproducer div.
Solid tests for AbortError + basepath
packages/solid-router/tests/loaders.test.tsx
Adds analogous test verifying AbortError on initial load with basepath does not render error component and basepath is preserved.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant App
  participant Router
  participant RouteLoader as Loader
  participant Head as executeHead
  participant UI as ErrorBoundary

  User->>App: Open "/"
  App->>Router: Initialize with basepath "/app"
  Router->>Loader: Run loader (initial load)
  note right of Loader: Abort due to basepath redirect
  Loader-->>Router: Throw DOMException(name="AbortError")

  alt AbortError
    Router->>Head: executeHead()
    Head-->>Router: headResult
    note over Router: Merge head, preserve/resolve match status
    Router-->>App: Render route content (no error)
    App-->>User: UI shows index under "/app"
  else Other errors
    Router->>UI: Propagate to error boundary
    UI-->>User: Error UI
  end

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • TanStack/router#4961 — Adjusts loader/error/executeHead interplay in router-core, touching the same loadMatches error pathway.

Suggested reviewers

  • schiller-manuel

Poem

A hop, a skip, the loaders race—
Abort! says basepath, shifting place.
No burrowed error, calm instead,
We nibble greens while running head.
The trail now starts at “/app”, hooray—
A rabbit routes the tidy way. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "fix(router-core): handle AbortError in router execution flow" succinctly and accurately describes the primary change (special-casing AbortError handling in router-core) and aligns with the modified files and added tests that target loader abort behavior; it is specific, concise, and relevant to the changeset.
Linked Issues Check ✅ Passed The changes directly address issue #4517 by adding special handling for DOMException 'AbortError' in packages/router-core/src/load-matches.ts to prevent the AbortError from bubbling into the ErrorBoundary, and by adding tests in react-router and solid-router that reproduce the basepath initial-load abort scenario and assert the app renders without showing the error route. These code and test updates match the linked issue's objective to avoid treating an unreasoned abort as an application error.
Out of Scope Changes Check ✅ Passed All modifications are limited to router-core logic and router-specific tests (react-router and solid-router) that validate the abort behavior; there are no changes to public/exported APIs or unrelated packages in the provided summary.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • [ ] 📝 Generate Docstrings
🧪 Generate unit tests
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment

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

coderabbitai[bot] avatar Sep 24 '25 02:09 coderabbitai[bot]

The tests can only pass after #5202 has been merged.

leesb971204 avatar Oct 13 '25 08:10 leesb971204

any update please?

ifxnas avatar Nov 28 '25 18:11 ifxnas

any update please?

According this comment, #5202 must be merged first.

leesb971204 avatar Dec 02 '25 04:12 leesb971204