Skip to content
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

[unstable_cache] Don't track dynamic fetches in an unstable_cache callback #65010

Merged
merged 4 commits into from
Apr 26, 2024

Conversation

wyattjoh
Copy link
Member

@wyattjoh wyattjoh commented Apr 24, 2024

What?

When pages are rendered using partial prerendering (PPR), they can easily trigger cases that attempt to interrupt static rendering. If a user calls fetch from within a unstable_cache callback with cache: "no-store", we currently break out, as that fetch operation is called within a cached callback.

Why?

Without this change, using unstable_cache would have limited affect when dealing with external code that explicitly sets cache: "no-store" preventing it from utilizing the user-specified-cache.

How?

This modifies the fetch patching so it doesn't bail static rendering due to dynamic fetches within an unstable_cache callback.

Closes NEXT-3220

@ijjk ijjk added created-by: Next.js team PRs by the Next.js team type: next labels Apr 24, 2024
Copy link
Member Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

Join @wyattjoh and the rest of your teammates on Graphite Graphite

@ijjk
Copy link
Member

ijjk commented Apr 24, 2024

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary vercel/next.js wyattjohnson/unstable-cache-fetch Change
buildDuration 18.5s 16.8s N/A
buildDurationCached 9.4s 9.1s N/A
nodeModulesSize 359 MB 359 MB ⚠️ +31.8 kB
nextStartRea..uration (ms) 466ms 464ms N/A
Client Bundles (main, webpack)
vercel/next.js canary vercel/next.js wyattjohnson/unstable-cache-fetch Change
1103-HASH.js gzip 31.8 kB 31.8 kB N/A
1a9f679d-HASH.js gzip 53.5 kB 53.5 kB N/A
335-HASH.js gzip 5.09 kB 5.09 kB N/A
7953.HASH.js gzip 169 B 169 B
framework-HASH.js gzip 45.2 kB 45.2 kB
main-app-HASH.js gzip 230 B 228 B N/A
main-HASH.js gzip 31.5 kB 31.5 kB N/A
webpack-HASH.js gzip 1.65 kB 1.65 kB N/A
Overall change 45.4 kB 45.4 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary vercel/next.js wyattjohnson/unstable-cache-fetch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary vercel/next.js wyattjohnson/unstable-cache-fetch Change
_app-HASH.js gzip 192 B 193 B N/A
_error-HASH.js gzip 192 B 193 B N/A
amp-HASH.js gzip 507 B 511 B N/A
css-HASH.js gzip 341 B 343 B N/A
dynamic-HASH.js gzip 2.52 kB 2.52 kB
edge-ssr-HASH.js gzip 266 B 265 B N/A
head-HASH.js gzip 362 B 365 B N/A
hooks-HASH.js gzip 392 B 392 B
image-HASH.js gzip 4.32 kB 4.32 kB N/A
index-HASH.js gzip 268 B 268 B
link-HASH.js gzip 2.69 kB 2.7 kB N/A
routerDirect..HASH.js gzip 329 B 328 B N/A
script-HASH.js gzip 397 B 397 B
withRouter-HASH.js gzip 324 B 324 B
1afbb74e6ecf..834.css gzip 106 B 106 B
Overall change 4 kB 4 kB
Client Build Manifests
vercel/next.js canary vercel/next.js wyattjohnson/unstable-cache-fetch Change
_buildManifest.js gzip 483 B 484 B N/A
Overall change 0 B 0 B
Rendered Page Sizes
vercel/next.js canary vercel/next.js wyattjohnson/unstable-cache-fetch Change
index.html gzip 528 B 528 B
link.html gzip 540 B 540 B
withRouter.html gzip 523 B 524 B N/A
Overall change 1.07 kB 1.07 kB
Edge SSR bundle Size
vercel/next.js canary vercel/next.js wyattjohnson/unstable-cache-fetch Change
edge-ssr.js gzip 94.7 kB 94.7 kB N/A
page.js gzip 3.07 kB 3.06 kB N/A
Overall change 0 B 0 B
Middleware size
vercel/next.js canary vercel/next.js wyattjohnson/unstable-cache-fetch Change
middleware-b..fest.js gzip 623 B 624 B N/A
middleware-r..fest.js gzip 156 B 156 B
middleware.js gzip 27.9 kB 27.9 kB N/A
edge-runtime..pack.js gzip 839 B 839 B
Overall change 995 B 995 B
Next Runtimes
vercel/next.js canary vercel/next.js wyattjohnson/unstable-cache-fetch Change
app-page-exp...dev.js gzip 171 kB 171 kB
app-page-exp..prod.js gzip 98.4 kB 98.4 kB
app-page-tur..prod.js gzip 99.9 kB 99.9 kB
app-page-tur..prod.js gzip 94.3 kB 94.3 kB
app-page.run...dev.js gzip 157 kB 157 kB
app-page.run..prod.js gzip 93 kB 93 kB
app-route-ex...dev.js gzip 21.4 kB 21.5 kB N/A
app-route-ex..prod.js gzip 15.2 kB 15.2 kB N/A
app-route-tu..prod.js gzip 15.2 kB 15.2 kB N/A
app-route-tu..prod.js gzip 14.9 kB 15 kB N/A
app-route.ru...dev.js gzip 21.3 kB 21.3 kB N/A
app-route.ru..prod.js gzip 14.9 kB 15 kB N/A
pages-api-tu..prod.js gzip 9.55 kB 9.55 kB
pages-api.ru...dev.js gzip 9.82 kB 9.82 kB
pages-api.ru..prod.js gzip 9.55 kB 9.55 kB
pages-turbo...prod.js gzip 21.4 kB 21.4 kB
pages.runtim...dev.js gzip 22.1 kB 22.1 kB
pages.runtim..prod.js gzip 21.4 kB 21.4 kB
server.runti..prod.js gzip 51.6 kB 51.6 kB
Overall change 859 kB 859 kB
build cache Overall increase ⚠️
vercel/next.js canary vercel/next.js wyattjohnson/unstable-cache-fetch Change
0.pack gzip 1.61 MB 1.62 MB ⚠️ +3.03 kB
index.pack gzip 112 kB 112 kB N/A
Overall change 1.61 MB 1.62 MB ⚠️ +3.03 kB
Diff details
Diff for edge-ssr.js

Diff too large to display

Diff for 1103-HASH.js

Diff too large to display

Diff for app-route-ex..ntime.dev.js

Diff too large to display

Diff for app-route-ex..time.prod.js

Diff too large to display

Diff for app-route-tu..time.prod.js

Diff too large to display

Diff for app-route-tu..time.prod.js

Diff too large to display

Diff for app-route.runtime.dev.js

Diff too large to display

Diff for app-route.ru..time.prod.js

Diff too large to display

Commit: f4d46f3

@ijjk ijjk added the tests label Apr 25, 2024
@wyattjoh wyattjoh marked this pull request as ready for review April 25, 2024 01:08
@ijjk
Copy link
Member

ijjk commented Apr 25, 2024

Failing test suites

Commit: 0f3670c

pnpm test-start test/e2e/app-dir/app-static/app-static-custom-handler.test.ts

  • app-dir static/dynamic handling > should output HTML/RSC files for static paths
Expand output

● app-dir static/dynamic handling › should output HTML/RSC files for static paths

expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `app-dir static/dynamic handling should output HTML/RSC files for static paths 1`

- Snapshot  - 1
+ Received  + 0

@@ -190,11 +190,10 @@
    "too-many-cache-tags/page_client-reference-manifest.js",
    "unstable-cache/dynamic-undefined/page.js",
    "unstable-cache/dynamic-undefined/page_client-reference-manifest.js",
    "unstable-cache/dynamic/page.js",
    "unstable-cache/dynamic/page_client-reference-manifest.js",
-   "unstable-cache/fetch/route.js",
    "variable-config-revalidate/revalidate-3.html",
    "variable-config-revalidate/revalidate-3.rsc",
    "variable-config-revalidate/revalidate-3/page.js",
    "variable-config-revalidate/revalidate-3/page_client-reference-manifest.js",
    "variable-revalidate-edge/body/page.js",

  640 |         })
  641 |
> 642 |       expect(files.sort()).toMatchInlineSnapshot(`
      |                            ^
  643 |         [
  644 |           "(new)/custom/page.js",
  645 |           "(new)/custom/page_client-reference-manifest.js",

  at Object.toMatchInlineSnapshot (e2e/app-dir/app-static/app-static.test.ts:642:28)

Read more about building and testing Next.js in contributing.md.

TURBOPACK=1 pnpm test-start test/production/app-dir/worker-restart/worker-restart.test.ts (turbopack)

  • worker-restart > should properly exhaust all restart attempts and not fail with any worker errors
Expand output

● worker-restart › should properly exhaust all restart attempts and not fail with any worker errors

expect(received).toContain(expected) // indexOf

Expected substring: "Static worker exited with code: null and signal: SIGTERM"
Received string:    "  ▲ Next.js 14.3.0-canary.23 (turbo)·
   Creating an optimized production build ...
next-swc build: local built @next/swc from NEXT_TEST_NATIVE_DIR
   Building (0/4) ...
   Building (1/4)··
   Building (2/4)··
   Building (3/4)··
 ✓ Building (4/4)
   Linting and checking validity of types ...
   Collecting page data ...
   Generating static pages (0/5) ...
   Generating static pages (1/5)··
   Generating static pages (2/5)··
   Generating static pages (3/5)···
 ⚠ The Next.js plugin was not detected in your ESLint configuration. See https://nextjs.org/docs/basic-features/eslint#migrating-existing-config
 ⚠ Sending SIGTERM signal to static worker due to timeout of 10 seconds. Subsequent errors may be a result of the worker exiting.
 ⚠ Restarted static page generation for /bad-page because it took more than 10 seconds
 ⚠ See more info here https://nextjs.org/docs/messages/static-page-generation-timeout
 ⚠ Sending SIGTERM signal to static worker due to timeout of 10 seconds. Subsequent errors may be a result of the worker exiting.
 ⚠ Restarted static page generation for /bad-page because it took more than 10 seconds
 ⚠ Sending SIGTERM signal to static worker due to timeout of 10 seconds. Subsequent errors may be a result of the worker exiting.·
> Build error occurred
Error: Static page generation for /bad-page is still timing out after 3 attempts. See more info here https://nextjs.org/docs/messages/static-page-generation-timeout

  294 |                 const pagePath = arg.path;
  295 |                 if (attempts >= 3) {
> 296 |                     throw new Error(`Static page generation for ${pagePath} is still timing out after 3 attempts. See more info here https://nextjs.org/docs/messages/static-page-generation-timeout`);
      |                           ^
  297 |                 }
  298 |                 _log.warn(`Restarted static page generation for ${pagePath} because it took more than ${timeout} seconds`);
  299 |             } else {

  at onRestart (../packages/next/dist/build/index.js:296:27)
  at ../packages/next/dist/lib/worker.js:98:40
  at ../async /root/actions-runner/_work/next.js/next.js/packages/next/dist/export/index.js:450:20
  at async Span.traceAsyncFn (../packages/next/dist/trace/trace.js:154:20)
  at ../async /root/actions-runner/_work/next.js/next.js/packages/next/dist/export/index.js:448:24
      at async Promise.all (index 2)
  at async exportAppImpl (../packages/next/dist/export/index.js:440:21)
  at ../async /root/actions-runner/_work/next.js/next.js/packages/next/dist/export/index.js:623:16
  at async Span.traceAsyncFn (../packages/next/dist/trace/trace.js:154:20)
  "
  at Object.toContain (production/app-dir/worker-restart/worker-restart.test.ts:14:20)

Read more about building and testing Next.js in contributing.md.

TURBOPACK=1 pnpm test-start test/e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts (turbopack)

  • parallel-routes-and-interception > parallel routes > should gracefully handle when two page segments match the children parallel slot
  • parallel-routes-and-interception > parallel routes > should throw a 404 when no matching parallel route is found
  • parallel-routes-and-interception > parallel routes > should render nested parallel routes
  • parallel-routes-and-interception > parallel routes > should support layout files in parallel routes
  • parallel-routes-and-interception > parallel routes > should only scroll to the parallel route that was navigated to
  • parallel-routes-and-interception > parallel routes > should apply the catch-all route to the parallel route if no matching route is found
  • parallel-routes-and-interception > parallel routes > should match the catch-all routes of the more specific path, if there is more than one catch-all route
  • parallel-routes-and-interception > parallel routes > should navigate with a link with prefetch=false
  • parallel-routes-and-interception > parallel routes > should display all parallel route params with useParams
  • parallel-routes-and-interception > parallel routes > should load CSS for a default page that exports another page
  • parallel-routes-and-interception > parallel routes > should handle a loading state
  • parallel-routes-and-interception > route intercepting > should render intercepted route
  • parallel-routes-and-interception > route intercepting > should render an intercepted route from a slot
  • parallel-routes-and-interception > route intercepting > should render an intercepted route at the top level from a nested path
  • parallel-routes-and-interception > route intercepting > should render intercepted route from a nested route
  • parallel-routes-and-interception > route intercepting > should re-render the layout on the server when it had a default child route
  • parallel-routes-and-interception > route intercepting > should render modal when paired with parallel routes
  • parallel-routes-and-interception > route intercepting > should support intercepting with beforeFiles rewrites
  • parallel-routes-and-interception > route intercepting > should support intercepting local dynamic sibling routes
  • parallel-routes-and-interception > route intercepting > should intercept on routes that contain hyphenated/special dynamic params
  • parallel-routes-and-interception > route intercepting with dynamic catch-all routes > should render intercepted route
  • parallel-routes-and-interception > route intercepting with dynamic optional catch-all routes > should render intercepted route
  • parallel-routes-and-interception > route intercepting with dynamic routes > should render intercepted route
Expand output

● parallel-routes-and-interception › parallel routes › should gracefully handle when two page segments match the children parallel slot

thrown: "Exceeded timeout of 60000 ms for a test.
Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout."

  184 |     })
  185 |
> 186 |     it('should gracefully handle when two page segments match the `children` parallel slot', async () => {
      |     ^
  187 |       await next.stop()
  188 |       await next.patchFile(
  189 |         'app/parallel/nested-2/page.js',

  at it (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:186:5)
  at describe (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:10:3)
  at Object.describe (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:5:1)

● parallel-routes-and-interception › parallel routes › should throw a 404 when no matching parallel route is found

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/parallel-tab-bar
Call log:
  - navigating to "http://localhost:34409/parallel-tab-bar", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:218:23)

● parallel-routes-and-interception › parallel routes › should render nested parallel routes

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/parallel-side-bar/nested/deeper
Call log:
  - navigating to "http://localhost:34409/parallel-side-bar/nested/deeper", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:237:23)

● parallel-routes-and-interception › parallel routes › should support layout files in parallel routes

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/parallel-layout
Call log:
  - navigating to "http://localhost:34409/parallel-layout", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:271:23)

● parallel-routes-and-interception › parallel routes › should only scroll to the parallel route that was navigated to

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/parallel-scroll
Call log:
  - navigating to "http://localhost:34409/parallel-scroll", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:290:23)

● parallel-routes-and-interception › parallel routes › should apply the catch-all route to the parallel route if no matching route is found

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/parallel-catchall
Call log:
  - navigating to "http://localhost:34409/parallel-catchall", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:302:23)

● parallel-routes-and-interception › parallel routes › should match the catch-all routes of the more specific path, if there is more than one catch-all route

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/parallel-nested-catchall
Call log:
  - navigating to "http://localhost:34409/parallel-nested-catchall", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:334:23)

● parallel-routes-and-interception › parallel routes › should navigate with a link with prefetch=false

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/parallel-prefetch-false
Call log:
  - navigating to "http://localhost:34409/parallel-prefetch-false", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:365:23)

● parallel-routes-and-interception › parallel routes › should display all parallel route params with useParams

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/parallel-dynamic/foo/bar
Call log:
  - navigating to "http://localhost:34409/parallel-dynamic/foo/bar", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:386:23)

● parallel-routes-and-interception › parallel routes › should load CSS for a default page that exports another page

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/default-css
Call log:
  - navigating to "http://localhost:34409/default-css", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:400:23)

● parallel-routes-and-interception › parallel routes › should handle a loading state

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/with-loading
Call log:
  - navigating to "http://localhost:34409/with-loading", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:428:23)

● parallel-routes-and-interception › route intercepting with dynamic routes › should render intercepted route

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/intercepting-routes-dynamic/photos
Call log:
  - navigating to "http://localhost:34409/intercepting-routes-dynamic/photos", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:485:23)

● parallel-routes-and-interception › route intercepting with dynamic optional catch-all routes › should render intercepted route

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/intercepting-routes-dynamic-catchall/photos
Call log:
  - navigating to "http://localhost:34409/intercepting-routes-dynamic-catchall/photos", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:523:23)

● parallel-routes-and-interception › route intercepting with dynamic catch-all routes › should render intercepted route

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/intercepting-routes-dynamic-catchall/photos
Call log:
  - navigating to "http://localhost:34409/intercepting-routes-dynamic-catchall/photos", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:568:23)

● parallel-routes-and-interception › route intercepting › should render intercepted route

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/intercepting-routes/feed
Call log:
  - navigating to "http://localhost:34409/intercepting-routes/feed", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:611:23)

● parallel-routes-and-interception › route intercepting › should render an intercepted route from a slot

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/
Call log:
  - navigating to "http://localhost:34409/", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:648:23)

● parallel-routes-and-interception › route intercepting › should render an intercepted route at the top level from a nested path

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/nested-link
Call log:
  - navigating to "http://localhost:34409/nested-link", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:678:23)

● parallel-routes-and-interception › route intercepting › should render intercepted route from a nested route

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/intercepting-routes/feed/nested
Call log:
  - navigating to "http://localhost:34409/intercepting-routes/feed/nested", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:702:23)

● parallel-routes-and-interception › route intercepting › should re-render the layout on the server when it had a default child route

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/parallel-non-intercepting
Call log:
  - navigating to "http://localhost:34409/parallel-non-intercepting", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:739:23)

● parallel-routes-and-interception › route intercepting › should render modal when paired with parallel routes

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/intercepting-parallel-modal/vercel
Call log:
  - navigating to "http://localhost:34409/intercepting-parallel-modal/vercel", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:763:23)

● parallel-routes-and-interception › route intercepting › should support intercepting with beforeFiles rewrites

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/foo
Call log:
  - navigating to "http://localhost:34409/foo", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:811:23)

● parallel-routes-and-interception › route intercepting › should support intercepting local dynamic sibling routes

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/intercepting-siblings
Call log:
  - navigating to "http://localhost:34409/intercepting-siblings", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:825:23)

● parallel-routes-and-interception › route intercepting › should intercept on routes that contain hyphenated/special dynamic params

page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:34409/interception-route-special-params/some-random-param
Call log:
  - navigating to "http://localhost:34409/interception-route-special-params/some-random-param", waiting until "load"

  274 |     opts?.beforePageLoad?.(page)
  275 |
> 276 |     await page.goto(url, { waitUntil: 'load' })
      |                ^
  277 |   }
  278 |
  279 |   back(options): BrowserInterface {

  at BrowserInterface.goto (lib/browsers/playwright.ts:276:16)
  at webdriver (lib/next-webdriver.ts:129:3)
  at Object.<anonymous> (e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts:861:23)

Read more about building and testing Next.js in contributing.md.

pnpm test-start test/e2e/app-dir/app-static/app-static.test.ts

  • app-dir static/dynamic handling > fetchCache config should supercede dynamic config when force-dynamic is used
  • app-dir static/dynamic handling > should output HTML/RSC files for static paths
Expand output

● app-dir static/dynamic handling › fetchCache config should supercede dynamic config when force-dynamic is used

expect(received).toBe(expected) // Object.is equality

Expected: "0.383804128387669"
Received: "0.35150055532456626"

  142 |         )
  143 |         expect($2('#data').text()).toBeTruthy()
> 144 |         expect($2('#data').text()).toBe(initData)
      |                                    ^
  145 |       })
  146 |     })
  147 |

  at toBe (e2e/app-dir/app-static/app-static.test.ts:144:36)
  at retry (lib/next-test-utils.ts:774:14)
  at Object.<anonymous> (e2e/app-dir/app-static/app-static.test.ts:139:7)

● app-dir static/dynamic handling › should output HTML/RSC files for static paths

expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `app-dir static/dynamic handling should output HTML/RSC files for static paths 1`

- Snapshot  - 1
+ Received  + 0

@@ -190,11 +190,10 @@
    "too-many-cache-tags/page_client-reference-manifest.js",
    "unstable-cache/dynamic-undefined/page.js",
    "unstable-cache/dynamic-undefined/page_client-reference-manifest.js",
    "unstable-cache/dynamic/page.js",
    "unstable-cache/dynamic/page_client-reference-manifest.js",
-   "unstable-cache/fetch/route.js",
    "variable-config-revalidate/revalidate-3.html",
    "variable-config-revalidate/revalidate-3.rsc",
    "variable-config-revalidate/revalidate-3/page.js",
    "variable-config-revalidate/revalidate-3/page_client-reference-manifest.js",
    "variable-revalidate-edge/body/page.js",

  640 |         })
  641 |
> 642 |       expect(files.sort()).toMatchInlineSnapshot(`
      |                            ^
  643 |         [
  644 |           "(new)/custom/page.js",
  645 |           "(new)/custom/page_client-reference-manifest.js",

  at Object.toMatchInlineSnapshot (e2e/app-dir/app-static/app-static.test.ts:642:28)

Read more about building and testing Next.js in contributing.md.

__NEXT_EXPERIMENTAL_PPR=true pnpm test-dev test/e2e/app-dir/navigation/navigation.test.ts (PPR)

  • app dir - navigation > browser back to a revalidated page > should load the page
Expand output

● app dir - navigation › browser back to a revalidated page › should load the page

page.waitForSelector: Timeout 60000ms exceeded.
Call log:
  - waiting for locator('#submit-button')

  421 |     return this.chain(() => {
  422 |       return page
> 423 |         .waitForSelector(selector, { timeout, state: 'attached' })
      |          ^
  424 |         .then(async (el) => {
  425 |           // it seems selenium waits longer and tests rely on this behavior
  426 |           // so we wait for the load event fire before returning

  at waitForSelector (lib/browsers/playwright.ts:423:10)

Read more about building and testing Next.js in contributing.md.

@wyattjoh wyattjoh force-pushed the wyattjohnson/unstable-cache-fetch branch from be30092 to 743c93c Compare April 25, 2024 16:17
@wyattjoh wyattjoh changed the title [unstable_cache] Don't patch fetch in an unstable_cache callback [unstable_cache] Don't track dynamic fetches in an unstable_cache callback Apr 25, 2024
@wyattjoh wyattjoh force-pushed the wyattjohnson/unstable-cache-fetch branch from 743c93c to ce02b1b Compare April 25, 2024 18:26
}
// If we aren't in a prerender, or we're in an unstable cache callback, we
// don't need to postpone.
if (!store.prerenderState || store.isUnstableCacheCallback) return
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the core change, during partial prerendering, it no longer marks the route as dynamic if we're in a unstable_cache callback.

@wyattjoh wyattjoh force-pushed the wyattjohnson/unstable-cache-fetch branch from 0f3670c to e9103c4 Compare April 26, 2024 17:38
@wyattjoh wyattjoh force-pushed the wyattjohnson/unstable-cache-fetch branch from e9103c4 to f4d46f3 Compare April 26, 2024 17:43
@ijjk ijjk enabled auto-merge (squash) April 26, 2024 18:12
@ijjk ijjk merged commit f64db55 into canary Apr 26, 2024
80 checks passed
@ijjk ijjk deleted the wyattjohnson/unstable-cache-fetch branch April 26, 2024 18:43
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants