Files
vercel__next.js/test/development/app-dir/cache-components-dev-errors/cache-components-dev-errors.test.ts
Jiwon Choi d7aa66c345 Remove generated error codes (#97687)
### Why?

Should come up with better solution that does not block PRs with git
conflict

x-ref:
https://vercel.slack.com/archives/C02CDC2ALJH/p1785263902728189?thread_ts=1785263687.502649&cid=C02CDC2ALJH

### How?

- Delete `errors.json`, the error-code SWC plugin, generated WASM, merge
driver, and validation/build tooling.
- Stop attaching error codes to server-rendering digests, redboxes, and
telemetry; native `Error.code` and `Error.name` remain available where
applicable.
- Remove the development-overlay error feedback UI, middleware, and
telemetry event that depended on stable codes.
- Update fixtures, snapshots, and guidance for code-free errors and
numeric-only digests.

<!-- NEXT_JS_LLM -->
2026-08-21 22:45:12 +02:00

191 lines
6.6 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import stripAnsi from 'strip-ansi'
import { nextTestSetup } from 'e2e-utils'
import {
waitForNoRedbox,
waitForNoErrorToast,
hasErrorToast,
retry,
} from 'next-test-utils'
import { outdent } from 'outdent'
describe('Cache Components Dev Errors', () => {
const { isTurbopack, next, isRspack } = nextTestSetup({
files: __dirname,
})
it('should show a red box error on the SSR render', async () => {
const browser = await next.browser('/error')
// TODO(veil): The "Page <anonymous>" frame should be omitted.
// Interestingly, it only appears on initial load, and not when
// soft-navigating to the page (see test below).
await expect(browser).toDisplayCollapsedRedbox(`
{
"description": "Next.js encountered the unstable value Math.random() while prerendering.",
"environmentLabel": "Server",
"label": "Blocking Route",
"source": "app/error/page.tsx (2:23) @ Page
> 2 | const random = Math.random()
| ^",
"stack": [
"Page app/error/page.tsx (2:23)",
"Page <anonymous>",
],
}
`)
})
it('should not show a red box error on client navigations', async () => {
const browser = await next.browser('/no-error')
await retry(async () => {
expect(await hasErrorToast(browser)).toBe(false)
})
await browser.elementByCss("[href='/error']").click()
await waitForNoErrorToast(browser)
await browser.loadPage(`${next.url}/error`)
// TODO: React should not include the anon stack in the Owner Stack.
await expect(browser).toDisplayCollapsedRedbox(`
{
"description": "Next.js encountered the unstable value Math.random() while prerendering.",
"environmentLabel": "Server",
"label": "Blocking Route",
"source": "app/error/page.tsx (2:23) @ Page
> 2 | const random = Math.random()
| ^",
"stack": [
"Page app/error/page.tsx (2:23)",
"Page <anonymous>",
],
}
`)
})
it('should not log unhandled rejections for persistently thrown top-level errors', async () => {
const cliOutputLength = next.cliOutput.length
const res = await next.fetch('/top-level-error')
expect(res.status).toBe(500)
await retry(() => {
const cliOutput = stripAnsi(next.cliOutput.slice(cliOutputLength))
expect(cliOutput).toContain('GET /top-level-error 500')
})
expect(next.cliOutput.slice(cliOutputLength)).not.toContain(
'unhandledRejection'
)
})
// NOTE: when update this snapshot, use `pnpm build` in packages/next to avoid next source code get mapped to source.
it('should display error when component accessed data without suspense boundary', async () => {
const outputIndex = next.cliOutput.length
const browser = await next.browser('/no-accessed-data')
await retry(() => {
expect(next.cliOutput.slice(outputIndex)).toContain(
'Error: Route "/no-accessed-data"'
)
})
expect(stripAnsi(next.cliOutput.slice(outputIndex))).toContain(
'https://nextjs.org/docs/messages/blocking-prerender-dynamic'
)
expect(stripAnsi(next.cliOutput.slice(outputIndex))).toContain(
'\n at Page (app/no-accessed-data/page.js:2:9)' +
'\n 1 | export default async function Page() {' +
'\n> 2 | await new Promise((r) => setTimeout(r, 200))' +
'\n | ^' +
'\n 3 | return <p>Page</p>' +
'\n 4 | }'
)
await expect(browser).toDisplayCollapsedRedbox(`
{
"description": "Next.js encountered uncached data during prerendering.",
"environmentLabel": "Server",
"label": "Blocking Route",
"source": "app/no-accessed-data/page.js (2:9) @ Page
> 2 | await new Promise((r) => setTimeout(r, 200))
| ^",
"stack": [
"Page app/no-accessed-data/page.js (2:9)",
],
}
`)
})
it('should clear segment errors after correcting them', async () => {
let browser: any
await next.patchFile(
'app/page.tsx',
outdent`
export const revalidate = 10
export default function Page() {
return (
<div>Hello World</div>
);
}
`,
async () => {
browser = await next.browser('/')
if (isTurbopack) {
await expect(browser).toDisplayRedbox(`
{
"description": "Route segment config "revalidate" is not compatible with \`nextConfig.cacheComponents\`. Please remove it.",
"environmentLabel": null,
"label": "Build Error",
"source": "./app/page.tsx (1:14)
Error: Route segment config "revalidate" is not compatible with \`nextConfig.cacheComponents\`. Please remove it.
> 1 | export const revalidate = 10
| ^^^^^^^^^^",
"stack": [],
}
`)
} else if (isRspack) {
await expect(browser).toDisplayRedbox(`
{
"description": " ╰─▶ × Error: x Route segment config "revalidate" is not compatible with \`nextConfig.cacheComponents\`. Please remove it.",
"environmentLabel": null,
"label": "Build Error",
"source": "./app/page.tsx
╰─▶ × Error: x Route segment config "revalidate" is not compatible with \`nextConfig.cacheComponents\`. Please remove it.
│ ,-[1:1]
│ 1 | export const revalidate = 10
│ : ^^^^^^^^^^
│ 2 | export default function Page() {
│ 3 | return (
│ 4 | <div>Hello World</div>
\`----
│",
"stack": [],
}
`)
} else {
await expect(browser).toDisplayRedbox(`
{
"description": " x Route segment config "revalidate" is not compatible with \`nextConfig.cacheComponents\`. Please remove it.",
"environmentLabel": null,
"label": "Build Error",
"source": "./app/page.tsx
Error: x Route segment config "revalidate" is not compatible with \`nextConfig.cacheComponents\`. Please remove it.
,-[1:1]
1 | export const revalidate = 10
: ^^^^^^^^^^
2 | export default function Page() {
3 | return (
4 | <div>Hello World</div>
\`----",
"stack": [],
}
`)
}
}
)
await waitForNoRedbox(browser)
})
})