-
Notifications
You must be signed in to change notification settings - Fork 30k
Turbopack: align chunk loading error name #86593
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export default function Async() { | ||
| return 'this is a lazy loaded async component' | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| 'use client' | ||
|
|
||
| import dynamic from 'next/dynamic' | ||
| import { Suspense } from 'react' | ||
|
|
||
| const Async = dynamic(() => import('./async'), { ssr: false }) | ||
|
|
||
| export default function Page() { | ||
| return ( | ||
| <> | ||
| <Suspense fallback={<div>Loading...</div>}> | ||
| <Async /> | ||
| </Suspense> | ||
| </> | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| export default function Layout({ children }) { | ||
| return ( | ||
| <html lang="en"> | ||
| <head /> | ||
| <body>{children}</body> | ||
| </html> | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| 'use client' | ||
|
|
||
| export default function Page() { | ||
| return <>this is other</> | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| import { nextTestSetup } from 'e2e-utils' | ||
| import { recursiveReadDir } from 'next/dist/lib/recursive-readdir' | ||
| import path from 'path' | ||
| import fs from 'fs' | ||
| import { retry } from 'next-test-utils' | ||
|
|
||
| describe('chunk-load-failure', () => { | ||
| const { next } = nextTestSetup({ | ||
| files: __dirname, | ||
| }) | ||
|
|
||
| async function getNextDynamicChunk() { | ||
| const chunksPath = path.join(next.testDir, '.next/static/') | ||
| const browserChunks = await recursiveReadDir(chunksPath, { | ||
| pathnameFilter: (f) => /\.js$/.test(f), | ||
| }) | ||
| let nextDynamicChunks = browserChunks.filter((f) => | ||
| fs | ||
| .readFileSync(path.join(chunksPath, f), 'utf8') | ||
| .includes('this is a lazy loaded async component') | ||
| ) | ||
| expect(nextDynamicChunks).toHaveLength(1) | ||
|
|
||
| return nextDynamicChunks[0] | ||
| } | ||
|
|
||
| it('should report async chunk load failures', async () => { | ||
| let nextDynamicChunk = await getNextDynamicChunk() | ||
|
|
||
| let pageError: Error | undefined | ||
| const browser = await next.browser('/dynamic', { | ||
| beforePageLoad(page) { | ||
| page.route('**/' + nextDynamicChunk, async (route) => { | ||
| await route.abort('connectionreset') | ||
| }) | ||
| page.on('pageerror', (error: Error) => { | ||
| pageError = error | ||
| }) | ||
| }, | ||
| }) | ||
|
|
||
| await retry(async () => { | ||
| const body = await browser.elementByCss('body') | ||
| expect(await body.text()).toMatch( | ||
| /Application error: a client-side exception has occurred while loading/ | ||
| ) | ||
| }) | ||
|
|
||
| expect(pageError).toBeDefined() | ||
| expect(pageError.name).toBe('ChunkLoadError') | ||
| if (process.env.IS_TURBOPACK_TEST) { | ||
| expect(pageError.message).toStartWith( | ||
| 'Failed to load chunk /_next/static/' + nextDynamicChunk | ||
| ) | ||
| } else { | ||
| expect(pageError.message).toMatch(/^Loading chunk \S+ failed./) | ||
| expect(pageError.message).toContain('/_next/static/' + nextDynamicChunk) | ||
| } | ||
| }) | ||
|
|
||
| it('should report aborted chunks when navigating away', async () => { | ||
| let nextDynamicChunk = await getNextDynamicChunk() | ||
|
|
||
| let resolve | ||
| try { | ||
| const browser = await next.browser('/dynamic', { | ||
| beforePageLoad(page) { | ||
| page.route('**/' + nextDynamicChunk, async (route) => { | ||
| // deterministically ensure that the async chunk is still loading during the navigation | ||
| await new Promise((r) => { | ||
| resolve = r | ||
| }) | ||
| }) | ||
| page.on('pageerror', (error: Error) => { | ||
| console.log('pageerror', error) | ||
| }) | ||
| }, | ||
| }) | ||
|
|
||
| await browser.get(next.url + '/other') | ||
|
|
||
| let body = await browser.elementByCss('body') | ||
| expect(await body.text()).toMatch('this is other') | ||
|
|
||
| const browserLogs = (await browser.log()).filter( | ||
| (m) => m.source === 'warning' || m.source === 'error' | ||
| ) | ||
|
|
||
| if (process.env.BROWSER_NAME === 'firefox') { | ||
| expect(browserLogs).toContainEqual( | ||
| expect.objectContaining({ | ||
| message: expect.stringContaining( | ||
| 'Loading failed for the <script> with source' | ||
| ), | ||
| }) | ||
| ) | ||
| } else { | ||
| // Chrome and Safari doesn't show any errors or warnings here | ||
| expect(browserLogs).toBeEmpty() | ||
| } | ||
| } finally { | ||
| // prevent hanging | ||
| resolve?.() | ||
| } | ||
| }) | ||
| }) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| /** @type {import('next').NextConfig} */ | ||
| const nextConfig = {} | ||
|
|
||
| export default nextConfig |
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Large diffs are not rendered by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is important as
Promise.rejectleads to a unhandled rejection even withcatchThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that was a preexisting problem though then? I didn't change that part?