Surface empty `generateStaticParams` as a redbox with a real stack (#95269)
Under Cache Components, a dynamic route whose `generateStaticParams`
returns an empty array is intentionally an error, but it surfaced badly:
in development the request failed with an uncaught error that left a
blank screen and a 500, and a production build printed the error without
a stack. The cause was that `throwEmptyGenerateStaticParamsError`
deliberately discarded the stack, because the throw happens in framework
code in `buildAppStaticPaths` after the user's function has already
returned, so there was no user frame to point at.
This change adds an SWC transform that gives the error a stack anchored
at the user's code. For a `page`, `layout`, or `default` file that
exports `generateStaticParams`, it emits a
`__next_create_empty_gsp_error` factory whose `new Error` is span-mapped
back to the source. It keys off the export rather than any declaration
named `generateStaticParams`, so it covers `export function`/`export
const`, `export { x as generateStaticParams }`, and `export {
generateStaticParams } from '...'`, while ignoring a same-named local
helper that is never exported. The anchor is the most specific
available: the `return []` literal when it is unambiguously the
function's only return, the declaration, or the export statement when
the body lives in another module. The transform is registered for both
bundlers, gated on Cache Components and excluded from the edge runtime,
mirroring the existing `debug_instant_stack` wiring.
At runtime the factory is attached to the segment as
`createEmptyParamsError` in `collectSegments`, and `buildAppStaticPaths`
throws it when it detects an empty result. Because the error now
originates in the page module rather than framework code, development
surfaces a proper redbox with a meaningful stack and production fails
the build with a stacked CLI error. The custom
`EmptyGenerateStaticParamsError` name has been dropped since it only
added noise to the logs. A few export forms, notably a wildcard `export
*` re-export, can't be detected from the page module alone, so when the
factory is absent the helper falls back to throwing the message with its
natural stack; those framework frames are ignore-listed in the output
but stay available for debugging.
The build-mode error does not yet include a code frame, because
`generateStaticParams` runs in the page-data worker, which lacks the
code-frame support that the prerender export worker has. That is left
for a follow-up. A new end-to-end test covers the redbox in development
for both a literal and a computed empty array, and asserts the per-route
build errors in production using `--debug-build-paths` so each route is
isolated. Transform fixtures cover the literal, computed,
preceding-statement, multiple-return, aliased-export, re-export, and
not-exported cases.