fix: refactor middleware
Summary by CodeRabbit
-
New Features
- Added a new page and navigation link for "Server Functions Middleware Unhandled Exception" E2E tests.
-
Bug Fixes
- Improved middleware execution and client/server error/redirect propagation for more consistent handling.
- Enhanced server response handling to support streaming and structured server-function payloads.
-
Chores
- Removed a legacy middleware export from the public API.
- Added a context header constant and updated client/server fetch plumbing to support the new server-function flow.
π€ 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 ed548799d38abe1a73c9ed3f9005833cec06fe35
| Command | Status | Duration | Result |
|---|---|---|---|
nx affected --targets=test:eslint,test:unit,tes... |
β Failed | 24m 27s | View β |
nx run-many --target=build --exclude=examples/*... |
β Succeeded | 28s | View β |
βοΈ Nx Cloud last updated this comment at 2025-10-19 21:07:11 UTC
Walkthrough
Adds a new E2E route /middleware/unhandled-exception with an auth middleware that throws; refactors server/client middleware and server-function request/response handling across start-client-core and start-server-core, and updates exports/constants and client fetcher behavior.
Changes
| Cohort / File(s) | Summary |
|---|---|
Route tree & registration e2e/react-start/server-functions/src/routeTree.gen.ts |
Import and register MiddlewareUnhandledExceptionRoute, add to rootRouteChildren, and include in FileRoutesByFullPath/FileRoutesByTo/FileRoutesById and TanStack Router augmentations. |
New route + navigation e2e/react-start/server-functions/src/routes/middleware/unhandled-exception.tsx, e2e/react-start/server-functions/src/routes/index.tsx |
New file route /middleware/unhandled-exception with authMiddleware (throws Unauthorized), personServerFn using middleware chain, loader and component; index adds nav link labeled "Server Functions Middleware Unhandled Exception E2E tests". |
Client middleware orchestration packages/start-client-core/src/createServerFn.ts, packages/start-client-core/src/index.tsx, packages/start-client-core/src/constants.ts |
Major refactor of middleware execution to callNextMiddleware/userNext wrapper flow, await middleware results, centralize error/redirect handling; removed public applyMiddleware export; added X_TSS_CONTEXT constant export. |
Client RPC / fetcher packages/start-client-core/src/client-rpc/serverFnFetcher.ts |
New handler parameter and proxied fetch path; adds serverFn headers, supports serialized/streamed server-function responses (NDJSON / cross-JSON), and reworks JSON/redirect/not-found handling. |
Server request/response handling packages/start-server-core/src/createStartHandler.ts, packages/start-server-core/src/server-functions-handler.ts |
Adjusted header checks (use x-tsr-createServerFn), removed middleware context propagation from execute call, added debug logging, added form-data detection, reworked payload parsing and response serialization (streaming NDJSON / cross-JSON), set X_TSS_RAW_RESPONSE for raw Responses. |
Small UI text change e2e/react-start/server-functions/src/routes/submit-post-formdata.tsx |
Minor copy update in displayed guidance text. |
Sequence Diagram(s)
sequenceDiagram
participant Client as Caller (client/serverFn)
participant Runner as createServerFn.execute
participant Chain as callNextMiddleware
participant MW as Middleware (authMiddleware / others)
participant Handler as Final Handler / ServerFn
participant Fetcher as serverFnFetcher
participant Server as start-server-core handler
Client->>Fetcher: invoke(serverFn args, handler)
Fetcher->>Server: proxied fetch with serverFn headers
Server->>Runner: handleServerAction -> execute middlewares
Runner->>Chain: start(index=0, ctx)
Chain->>MW: execute(ctx, userNext)
alt MW calls userNext
MW->>Chain: userNext(mergedCtx) -> next index
else MW throws
MW-->>Runner: error (propagated)
end
opt reached handler
Chain->>Handler: invoke with final ctx
Handler-->>Server: result or error
end
Server-->>Fetcher: serialized or raw response (NDJSON/JSON/Response)
Fetcher-->>Client: parsed/streamed result or redirect/error
Estimated code review effort
π― 5 (Critical) | β±οΈ ~120+ minutes
Areas needing extra attention:
- packages/start-client-core/src/createServerFn.ts β new middleware control-flow, userNext semantics, and removal of applyMiddleware.
- packages/start-client-core/src/client-rpc/serverFnFetcher.ts β streaming/NDJSON and proxied fetch handling.
- packages/start-server-core/src/server-functions-handler.ts β serializeResult and ctx-result unwrapping, Content-Type/X_TSS headers and Response construction.
- Integration between client fetcher and server serialized responses (headers: x-tsr-createServerFn, x-tsr-serverFn, X_TSS_RAW_RESPONSE, X_TSS_SERIALIZED).
Possibly related PRs
- TanStack/router#5276 β Related changes affecting middleware orchestration and exports in start-client-core (server-function flow).
- TanStack/router#5513 β Overlaps in server-functions infrastructure edits touching server-functions-handler and createStartHandler.
- TanStack/router#5040 β Related modifications to server-function abstractions across client/server core packages.
Suggested reviewers
- schiller-manuel
Poem
π° I hopped through middleware, one by one,
A token tossed, an Unauthorized run,
I built a route for tests at dawn,
Streams and headers hum alongβ
I nibble logs and hum this song.
Pre-merge checks and finishing touches
β Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | β οΈ Warning | Docstring coverage is 22.22% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
β Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | β Passed | Check skipped - CodeRabbitβs high-level summary is enabled. |
| Title Check | β Passed | The PR title "fix: refactor middleware" is related to the primary changes in the changeset, particularly the significant middleware execution refactoring in packages/start-client-core/src/createServerFn.ts. This file underwent substantial changes including reworked client/server execution flow, expanded server-side middleware handling, middleware execution refactoring with new internal wrappers, and enhanced error handling. Supporting changes across multiple files (serverFnFetcher.ts, server-functions-handler.ts, createStartHandler.ts) appear designed to integrate and support this middleware refactoring. The title accurately captures the core intent of the PR, though it does not encompass the full scope of related server function handling changes. |
β¨ Finishing touches
- [ ] π Generate docstrings
π§ͺ Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
- [ ] Commit unit tests in branch
fix/refactor-middleware
Comment @coderabbitai help to get the list of available commands and usage tips.
More templates
- tanstack-router-solid-example-basic
- tanstack-router-solid-example-basic-devtools-panel
- tanstack-router-solid-example-basic-file-based
- tanstack-router-solid-example-basic-non-nested-devtools
- tanstack-router-solid-example-basic-solid-query
- tanstack-router-solid-example-basic-solid-query-file-based
- tanstack-router-solid-example-basic-ssr-streaming-file-based
- tanstack-router-solid-example-kitchen-sink-file-based
- tanstack-router-solid-example-quickstart-file-based
- tanstack-solid-start-example-bare
- tanstack-solid-start-example-basic
- tanstack-solid-start-example-basic-static
- tanstack-router-react-example-authenticated-routes
- tanstack-router-react-example-authenticated-routes-firebase
- tanstack-router-react-example-basic
- tanstack-router-react-example-basic-default-search-params
- tanstack-router-react-example-basic-devtools-panel
- tanstack-router-react-example-basic-file-based
- tanstack-router-react-example-basic-non-nested-devtools
- tanstack-router-react-example-react-query
- tanstack-router-react-example-basic-react-query-file-based
- tanstack-router-react-example-basic-ssr-file-based
- tanstack-router-react-example-basic-ssr-streaming-file-based
- tanstack-router-react-example-basic-virtual-file-based
- tanstack-router-react-example-basic-virtual-inside-file-based
- tanstack-router-react-example-deferred-data
- tanstack-router-i18n-paraglide
- tanstack-router-react-example-kitchen-sink
- tanstack-router-react-example-kitchen-sink-file-based
- tanstack-router-react-example-kitchen-sink-react-query
- tanstack-router-react-example-kitchen-sink-react-query-file-based
- tanstack-router-react-example-large-file-based
- tanstack-router-react-example-location-masking
- tanstack-router-react-example-navigation-blocking
- tanstack-router-react-example-quickstart
- tanstack-router-react-example-quickstart-esbuild-file-based
- tanstack-router-react-example-quickstart-file-based
- tanstack-router-react-example-quickstart-rspack-file-based
- tanstack-router-react-example-quickstart-webpack-file-based
- router-monorepo-react-query
- router-mono-simple
- router-mono-simple-lazy
- tanstack-router-react-example-scroll-restoration
- tanstack-search-validator-adapters
- tanstack-start-example-bare
- tanstack-start-example-basic
- tanstack-start-example-basic-auth
- tanstack-start-example-basic-cloudflare
- tanstack-start-example-basic-react-query
- tanstack-start-example-basic-static
- tanstack-start-bun-hosting
- tanstack-start-example-clerk-basic
- tanstack-start-example-convex-trellaux
- tanstack-start-example-counter
- tanstack-start-i18n-paraglide
- tanstack-start-example-large
- tanstack-start-example-material-ui
- tanstack-start-streaming-data-from-server-functions
- tanstack-start-example-supabase-basic
- tanstack-start-tailwind-v4
- tanstack-start-example-trellaux
- tanstack-start-example-workos
- tanstack-router-react-example-view-transitions
- tanstack-router-react-example-with-framer-motion
- tanstack-router-react-example-with-trpc
- tanstack-router-react-example-with-trpc-react-query
@tanstack/arktype-adapter
npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@5517
@tanstack/directive-functions-plugin
npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@5517
@tanstack/eslint-plugin-router
npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@5517
@tanstack/history
npm i https://pkg.pr.new/TanStack/router/@tanstack/history@5517
@tanstack/nitro-v2-vite-plugin
npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@5517
@tanstack/react-router
npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@5517
@tanstack/react-router-devtools
npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@5517
@tanstack/react-router-ssr-query
npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@5517
@tanstack/react-start
npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@5517
@tanstack/react-start-client
npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@5517
@tanstack/react-start-server
npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@5517
@tanstack/router-cli
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@5517
@tanstack/router-core
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@5517
@tanstack/router-devtools
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@5517
@tanstack/router-devtools-core
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@5517
@tanstack/router-generator
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@5517
@tanstack/router-plugin
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@5517
@tanstack/router-ssr-query-core
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@5517
@tanstack/router-utils
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@5517
@tanstack/router-vite-plugin
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@5517
@tanstack/server-functions-plugin
npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@5517
@tanstack/solid-router
npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@5517
@tanstack/solid-router-devtools
npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@5517
@tanstack/solid-start
npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@5517
@tanstack/solid-start-client
npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@5517
@tanstack/solid-start-server
npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@5517
@tanstack/start-client-core
npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@5517
@tanstack/start-plugin-core
npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@5517
@tanstack/start-server-core
npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@5517
@tanstack/start-static-server-functions
npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@5517
@tanstack/start-storage-context
npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@5517
@tanstack/valibot-adapter
npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@5517
@tanstack/virtual-file-routes
npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@5517
@tanstack/zod-adapter
npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@5517
commit: ed54879
Is there anything that's blocking this PR from progressing?
Quite a few of the open issues marked under the label needed-for-start-stable are ones involved with middleware handling.
Just quickly going through this PR, it looks like it might be possible to resolve a few of them if this development completes and gets merged.
(Not trying to pressure you guys to rush anything :) just want to express that I'm sure many of us would be happy to see this PR land)