fix: pages router instrumentation error reporting for api routes#334
fix: pages router instrumentation error reporting for api routes#334james-elicx merged 4 commits intomainfrom
Conversation
commit: |
|
|
/bigbonk review |
There was a problem hiding this comment.
Review: test: pages router instrumentation
Good PR — these are well-structured regression tests for a real bug (startup crash from ssrLoadModule during configureServer in Vite 7). The code is clean and the test design is sound. A few observations:
What works well
-
Separate
describeblocks for startup vs per-request tests. The startup tests correctly avoid resetting state (sinceregister()fires once), while theonRequestErrortests usebeforeEachto reset. This is a thoughtful design that prevents test ordering issues. -
globalThisbridge pattern. Theinstrumentation-state.tsmodule correctly usesglobalThisto share state across Vite's separate module graphs (instrumentation runner vs SSR). The comment block explaining why this is necessary (lines 1-18 ofinstrumentation-state.ts) is excellent — this is a subtle Vite architecture detail that would otherwise confuse future contributors. -
Regression is self-documenting. If the startup crash regresses, the Playwright
webServerwill fail to connect and the test never runs — which means the test suite itself is the regression detector, not just the assertions.
Suggestions
-
Missing
onRequestErrortrigger test. TheonRequestErrordescribe block only tests the negative case (successful requests don't trigger it). There's no test that actually triggers an error and verifiesonRequestErrorcaptures it. This would be the most valuable assertion for theonRequestErrorpath — without it, you're only testing that the handler doesn't fire, not that it does. Consider adding a fixture route that throws and assertingerrors.length > 0with correctrouterKind/routePath/routeTypevalues. -
Hardcoded
setTimeoutfor async settling (instrumentation.spec.ts:74). The 200ms sleep works but is fragile — it could flake on slow CI runners or if the async path changes. Since the test immediately follows with a synchronous API call that reads the state, and the state is set synchronously within the same process viaglobalThis, the sleep may not even be necessary. If it is needed, consider polling the state endpoint with a short retry loop instead. -
_errors()lazy init could mask bugs (instrumentation-state.ts:32-37). The_errors()helper silently creates the array if it doesn't exist. This meansgetCapturedErrors()never returnsundefined— even ifresetInstrumentationState()was never called. This is fine for test ergonomics, but worth noting that it hides the distinction between "state was initialized and empty" vs "state was never initialized." -
Type assertion density in
instrumentation-state.ts. The(globalThis as any)casts appear 6 times. A small helper or typed global declaration would clean this up:const g = globalThis as Record<string, unknown>;
Minor style nit, not blocking.
Verdict
The tests cover the critical regression (startup crash) well. The main gap is the missing positive test for onRequestError — right now you're testing that instrumentation loads and that successful requests don't trigger errors, but not that errors are actually captured. Adding that would make this a complete instrumentation test suite.
Looks good otherwise. Clean code, good comments, correct use of the fixture patterns.
|
Review posted on PR #334. Here's a summary: Overall: Good PR. The regression tests are well-structured and cover the critical startup crash from Key feedback:
The startup crash regression is well-covered — if the bug regresses, Playwright's |
|
/bigbonk re-review please |
There was a problem hiding this comment.
Re-review: fix: pages router instrumentation error reporting for api routes
All CI checks pass. The main gap from the first review (missing positive onRequestError test) was addressed in the second commit. The test suite now covers both the positive and negative cases.
Previous feedback — status
-
Missing positive
onRequestErrortest — Fixed. The second commit (7b9d7d7) added three tests: error capture with field assertions, route path pattern check, and multiple independent error accumulation. This was the most important gap and it's well-addressed. -
Hardcoded
setTimeout— Still present (200ms at lines 74, 92, 114; 400ms at line 130). Acceptable for now sincereportRequestErroris fire-and-forget (.catch(() => {})) so there's no way to synchronously wait on it. The timeouts are generous enough for CI. If these flake in practice, a polling loop would be the fix, but not blocking. -
(globalThis as any)repetition — Still present. Minor style nit, not blocking. -
_errors()lazy init — Still present. Fine for test code.
New observations
-
routeType: "render"for API routes (api-handler.ts:220) — Next.js uses"route"for API/route handlers (and the App Router codepath inapp-dev-server.ts:1918correctly uses"route"). Using"render"here is semantically wrong for an API endpoint. The test at line 105 assertsrouteTypeis"render", so both the implementation and the test are consistently wrong. This should be"route"to match Next.js behavior.The
OnRequestErrorContexttype already defines"route"as a valid value, so this is a one-line fix inapi-handler.tsand a one-line fix in the test. -
Stray tab at
instrumentation.spec.ts:106— Line 106 (\t});) uses a tab while the rest of the file uses spaces. The linter doesn't catch it, but it's visually inconsistent. Cosmetic. -
PR description mentions
cloudflare-devadded to CI matrix — This was actually done in PR #333, not this PR. The description should be corrected to avoid confusion in the commit history. -
examples/app-router-cloudflare/pages/index.tsx— This file is unrelated to instrumentation. The commit message ("add pages route to app dir") suggests it's verifying that App Router works when apages/directory coexists. Fine to include, but worth mentioning in the PR description since it's a separate concern.
Verdict
The core change (adding reportRequestError to api-handler.ts) is correct and well-tested. The routeType: "render" vs "route" issue is the only functional concern — it's a behavioral mismatch with Next.js. Everything else is minor. CI is fully green.
|
Review posted on PR #334. Here's the summary: Approved — the main gap from the first review (missing positive One functional concern: Minor nits: stray tab at |
fix: instrumentation.ts Pages Router support + onRequestError for API routes
Extends instrumentation.ts support to Pages Router and fixes a gap where
onRequestErrorwas never called for API route errors.What changed
onRequestErrorin API route handlerapi-handler.tscaught errors from Pages Router API routes but never calledreportRequestError, soonRequestErrorwould silently not fire for anypages/api/*handler. Added the call in the catch block withrouterKind: "Pages Router"androuteType: "render".Pages Router fixture
tests/fixtures/pages-basicgetsinstrumentation.ts,instrumentation-state.ts,/api/instrumentation-test, and/api/error-routeto support the new e2e tests. The state module usesglobalThiskeys rather than plain module-level variables — necessary becauseregister()runs in an isolatedModuleRunnermodule graph (separate from the Vite SSR graph that handles API routes), so plain exports wouldn't be shared between them.Pages Router e2e spec
tests/e2e/pages-router/instrumentation.spec.tscovers:instrumentation.tsis present (regression guard for theoutsideEmittercrash)register()was called before the first requestonRequestError()fires when an API handler throws, with correctrouterKind/routeType/routePathonRequestErrorcloudflare-devadded to CI matrixThe
**cloudflare-dev` added to CI matrix**The
cloudflare-devPlaywright project was missing from the CI matrix despite existing inplaywright.config.ts. Added it so the Vite dev +@cloudflare/vite-pluginstartup tests run in CI.