[PR #330] [MERGED] fix: register instrumentation in rsc entry and put error handler in global scope #482

Closed
opened 2026-05-06 13:08:19 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/330
Author: @james-elicx
Created: 3/7/2026
Status: Merged
Merged: 3/7/2026
Merged by: @james-elicx

Base: mainHead: j-branch-2


📝 Commits (4)

  • b1e98b5 test: instrumentation
  • 051f3a4 store onRequestError on globalThis
  • aae5e41 add instrumentation registration app-dev-server
  • 8d80bb2 guard against double calling runinstrumentation for appdir

📊 Changes

15 files changed (+471 additions, -23 deletions)

View changed files

examples/app-router-cloudflare/app/api/error-route/route.ts (+5 -0)
examples/app-router-cloudflare/app/api/instrumentation-test/route.ts (+29 -0)
examples/app-router-cloudflare/instrumentation-state.ts (+51 -0)
examples/app-router-cloudflare/instrumentation.ts (+52 -0)
📝 examples/app-router-cloudflare/tsconfig.json (+1 -1)
📝 packages/vinext/src/global.d.ts (+14 -1)
📝 packages/vinext/src/index.ts (+8 -2)
📝 packages/vinext/src/server/app-dev-server.ts (+19 -0)
📝 packages/vinext/src/server/instrumentation.ts (+45 -14)
📝 playwright.config.ts (+16 -5)
tests/e2e/app-router/instrumentation.spec.ts (+121 -0)
tests/fixtures/app-basic/app/api/instrumentation-test/route.ts (+29 -0)
tests/fixtures/app-basic/instrumentation-state.ts (+39 -0)
tests/fixtures/app-basic/instrumentation.ts (+38 -0)
📝 tests/instrumentation.test.ts (+4 -0)

📄 Description

Instrumentation.ts: App Router support + Cloudflare Workers e2e tests

Completes instrumentation.ts support for App Router, and adds e2e coverage that runs against the production Cloudflare Workers build.

What changed

Core: register() baked into the RSC entry

Previously runInstrumentation() was called from configureServer() in the host Node.js process. This broke with @cloudflare/vite-plugin because the plugin runs the RSC environment inside a miniflare Worker subprocess — a separate process from the host, with its own globalThis. Calling register() in the host meant it never ran in the same process as request handling.

The fix: generateRscEntry() now accepts an instrumentationPath parameter and emits register() as a top-level await at module evaluation time, before any requests are served. This runs in whatever process/environment evaluates the RSC entry — the Worker subprocess in Cloudflare dev, the RSC Vite environment with @vitejs/plugin-rsc, or the built Worker binary in production.

configureServer() still calls runInstrumentation() for Pages Router only, where there is no RSC entry and @cloudflare/vite-plugin is never present.

onRequestError handler storage

The handler is now stored on globalThis.__VINEXT_onRequestErrorHandler__ instead of a module-level variable. This makes it visible across the RSC and SSR Vite environment module graphs (separate instances, shared globalThis) and inside the Cloudflare Worker (single global scope). The key is declared in global.d.ts for type safety.

e2e coverage

  • tests/e2e/app-router/instrumentation.spec.ts — new spec covering register() startup, onRequestError() on route throws, multiple error capture, and no false positives on success. Uses relative URLs + Playwright baseURL so it's portable across projects.
  • The cloudflare-workers Playwright project now picks up this spec via testMatch, running the same assertions against the production wrangler build on port 4176.
  • app-router-cloudflare example gets instrumentation.ts, instrumentation-state.ts, /api/instrumentation-test, and /api/error-route to support the tests.

Unit tests

tests/instrumentation.test.ts gets a beforeEach cleanup of globalThis.__VINEXT_onRequestErrorHandler__ to prevent handler bleed between tests after the storage change.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/330 **Author:** [@james-elicx](https://github.com/james-elicx) **Created:** 3/7/2026 **Status:** ✅ Merged **Merged:** 3/7/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `j-branch-2` --- ### 📝 Commits (4) - [`b1e98b5`](https://github.com/cloudflare/vinext/commit/b1e98b51577ef0f8e56e19cec1db015632d8747a) test: instrumentation - [`051f3a4`](https://github.com/cloudflare/vinext/commit/051f3a4f69689222f7d7c4fb93ec5620cc8472e6) store onRequestError on globalThis - [`aae5e41`](https://github.com/cloudflare/vinext/commit/aae5e41a1870719845ed83237804f8b5fad701d2) add instrumentation registration app-dev-server - [`8d80bb2`](https://github.com/cloudflare/vinext/commit/8d80bb2f3c2300571cb003beaf5301e950bfea42) guard against double calling runinstrumentation for appdir ### 📊 Changes **15 files changed** (+471 additions, -23 deletions) <details> <summary>View changed files</summary> ➕ `examples/app-router-cloudflare/app/api/error-route/route.ts` (+5 -0) ➕ `examples/app-router-cloudflare/app/api/instrumentation-test/route.ts` (+29 -0) ➕ `examples/app-router-cloudflare/instrumentation-state.ts` (+51 -0) ➕ `examples/app-router-cloudflare/instrumentation.ts` (+52 -0) 📝 `examples/app-router-cloudflare/tsconfig.json` (+1 -1) 📝 `packages/vinext/src/global.d.ts` (+14 -1) 📝 `packages/vinext/src/index.ts` (+8 -2) 📝 `packages/vinext/src/server/app-dev-server.ts` (+19 -0) 📝 `packages/vinext/src/server/instrumentation.ts` (+45 -14) 📝 `playwright.config.ts` (+16 -5) ➕ `tests/e2e/app-router/instrumentation.spec.ts` (+121 -0) ➕ `tests/fixtures/app-basic/app/api/instrumentation-test/route.ts` (+29 -0) ➕ `tests/fixtures/app-basic/instrumentation-state.ts` (+39 -0) ➕ `tests/fixtures/app-basic/instrumentation.ts` (+38 -0) 📝 `tests/instrumentation.test.ts` (+4 -0) </details> ### 📄 Description **Instrumentation.ts: App Router support + Cloudflare Workers e2e tests** Completes `instrumentation.ts` support for App Router, and adds e2e coverage that runs against the production Cloudflare Workers build. ## What changed **Core: `register()` baked into the RSC entry** Previously `runInstrumentation()` was called from `configureServer()` in the host Node.js process. This broke with `@cloudflare/vite-plugin` because the plugin runs the RSC environment inside a miniflare Worker subprocess — a separate process from the host, with its own `globalThis`. Calling `register()` in the host meant it never ran in the same process as request handling. The fix: `generateRscEntry()` now accepts an `instrumentationPath` parameter and emits `register()` as a top-level `await` at module evaluation time, before any requests are served. This runs in whatever process/environment evaluates the RSC entry — the Worker subprocess in Cloudflare dev, the RSC Vite environment with `@vitejs/plugin-rsc`, or the built Worker binary in production. `configureServer()` still calls `runInstrumentation()` for Pages Router only, where there is no RSC entry and `@cloudflare/vite-plugin` is never present. **`onRequestError` handler storage** The handler is now stored on `globalThis.__VINEXT_onRequestErrorHandler__` instead of a module-level variable. This makes it visible across the RSC and SSR Vite environment module graphs (separate instances, shared `globalThis`) and inside the Cloudflare Worker (single global scope). The key is declared in `global.d.ts` for type safety. **e2e coverage** - `tests/e2e/app-router/instrumentation.spec.ts` — new spec covering `register()` startup, `onRequestError()` on route throws, multiple error capture, and no false positives on success. Uses relative URLs + Playwright `baseURL` so it's portable across projects. - The `cloudflare-workers` Playwright project now picks up this spec via `testMatch`, running the same assertions against the production wrangler build on port 4176. - `app-router-cloudflare` example gets `instrumentation.ts`, `instrumentation-state.ts`, `/api/instrumentation-test`, and `/api/error-route` to support the tests. **Unit tests** `tests/instrumentation.test.ts` gets a `beforeEach` cleanup of `globalThis.__VINEXT_onRequestErrorHandler__` to prevent handler bleed between tests after the storage change. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:08:19 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#482
No description provided.