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

Restore and enhance error handling for hanging inputs in "use cache" #74652

Merged
merged 13 commits into from
Jan 22, 2025

Conversation

unstubbable
Copy link
Contributor

@unstubbable unstubbable commented Jan 8, 2025

Uncached and forever hanging promises are currently not supported as input for "use cache" functions. One prominent example of this is the use of searchParams in a page with "use cache". Until Next.js version 15.1.1, the usage of such inputs led to an error during build after a timeout of 50 seconds. This behaviour relied on a bug in decodeReply though, and was hence broken after React fixed the bug. A build will now fail early with Error: Connection closed..

With this PR, we are restoring the timeout error behaviour by switching to the new decodeReplyFromAsyncIterable API, which allows us to keep an open stream when decoding the cached function's arguments.

In addition, in dev mode, we are now also propagating the error to the dev overlay.

@ijjk
Copy link
Member

ijjk commented Jan 8, 2025

Tests Passed

@ijjk
Copy link
Member

ijjk commented Jan 8, 2025

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary vercel/next.js hl/use-cache-hanging-inputs-error-handling Change
buildDuration 18.6s 15.7s N/A
buildDurationCached 14.6s 12.5s N/A
nodeModulesSize 418 MB 418 MB ⚠️ +35.6 kB
nextStartRea..uration (ms) 396ms 398ms N/A
Client Bundles (main, webpack)
vercel/next.js canary vercel/next.js hl/use-cache-hanging-inputs-error-handling Change
5306-HASH.js gzip 54 kB 54 kB N/A
8276.HASH.js gzip 169 B 168 B N/A
8377-HASH.js gzip 5.44 kB 5.44 kB N/A
bccd1874-HASH.js gzip 52.9 kB 52.9 kB
framework-HASH.js gzip 57.5 kB 57.5 kB N/A
main-app-HASH.js gzip 241 B 242 B N/A
main-HASH.js gzip 34.4 kB 34.4 kB N/A
webpack-HASH.js gzip 1.71 kB 1.71 kB N/A
Overall change 52.9 kB 52.9 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary vercel/next.js hl/use-cache-hanging-inputs-error-handling Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB
Overall change 39.4 kB 39.4 kB
Client Pages
vercel/next.js canary vercel/next.js hl/use-cache-hanging-inputs-error-handling Change
_app-HASH.js gzip 193 B 193 B
_error-HASH.js gzip 193 B 193 B
amp-HASH.js gzip 512 B 510 B N/A
css-HASH.js gzip 343 B 342 B N/A
dynamic-HASH.js gzip 1.84 kB 1.84 kB
edge-ssr-HASH.js gzip 265 B 265 B
head-HASH.js gzip 363 B 362 B N/A
hooks-HASH.js gzip 393 B 392 B N/A
image-HASH.js gzip 4.57 kB 4.57 kB N/A
index-HASH.js gzip 268 B 268 B
link-HASH.js gzip 2.35 kB 2.34 kB N/A
routerDirect..HASH.js gzip 328 B 328 B
script-HASH.js gzip 397 B 397 B
withRouter-HASH.js gzip 323 B 326 B N/A
1afbb74e6ecf..834.css gzip 106 B 106 B
Overall change 3.59 kB 3.59 kB
Client Build Manifests
vercel/next.js canary vercel/next.js hl/use-cache-hanging-inputs-error-handling Change
_buildManifest.js gzip 749 B 747 B N/A
Overall change 0 B 0 B
Rendered Page Sizes
vercel/next.js canary vercel/next.js hl/use-cache-hanging-inputs-error-handling Change
index.html gzip 523 B 523 B
link.html gzip 538 B 537 B N/A
withRouter.html gzip 519 B 520 B N/A
Overall change 523 B 523 B
Edge SSR bundle Size
vercel/next.js canary vercel/next.js hl/use-cache-hanging-inputs-error-handling Change
edge-ssr.js gzip 129 kB 129 kB N/A
page.js gzip 208 kB 208 kB N/A
Overall change 0 B 0 B
Middleware size
vercel/next.js canary vercel/next.js hl/use-cache-hanging-inputs-error-handling Change
middleware-b..fest.js gzip 669 B 666 B N/A
middleware-r..fest.js gzip 155 B 156 B N/A
middleware.js gzip 31.3 kB 31.3 kB N/A
edge-runtime..pack.js gzip 844 B 844 B
Overall change 844 B 844 B
Next Runtimes
vercel/next.js canary vercel/next.js hl/use-cache-hanging-inputs-error-handling Change
274-experime...dev.js gzip 322 B 322 B
274.runtime.dev.js gzip 314 B 314 B
app-page-exp...dev.js gzip 374 kB 374 kB N/A
app-page-exp..prod.js gzip 130 kB 130 kB
app-page-tur..prod.js gzip 143 kB 143 kB
app-page-tur..prod.js gzip 139 kB 139 kB
app-page.run...dev.js gzip 362 kB 362 kB N/A
app-page.run..prod.js gzip 126 kB 126 kB
app-route-ex...dev.js gzip 37.6 kB 37.6 kB
app-route-ex..prod.js gzip 25.6 kB 25.6 kB
app-route-tu..prod.js gzip 25.6 kB 25.6 kB
app-route-tu..prod.js gzip 25.4 kB 25.4 kB
app-route.ru...dev.js gzip 39.2 kB 39.2 kB
app-route.ru..prod.js gzip 25.4 kB 25.4 kB
pages-api-tu..prod.js gzip 9.69 kB 9.69 kB
pages-api.ru...dev.js gzip 11.6 kB 11.6 kB
pages-api.ru..prod.js gzip 9.68 kB 9.68 kB
pages-turbo...prod.js gzip 21.9 kB 21.9 kB
pages.runtim...dev.js gzip 27.7 kB 27.7 kB
pages.runtim..prod.js gzip 21.9 kB 21.9 kB
server.runti..prod.js gzip 916 kB 916 kB N/A
Overall change 820 kB 820 kB
build cache Overall increase ⚠️
vercel/next.js canary vercel/next.js hl/use-cache-hanging-inputs-error-handling Change
0.pack gzip 2.09 MB 2.1 MB ⚠️ +1.81 kB
index.pack gzip 75.2 kB 75 kB N/A
Overall change 2.09 MB 2.1 MB ⚠️ +1.81 kB
Diff details
Diff for edge-ssr.js

Diff too large to display

Diff for main-HASH.js

Diff too large to display

Diff for app-page-exp..ntime.dev.js

Diff too large to display

Diff for app-page.runtime.dev.js

Diff too large to display

Diff for server.runtime.prod.js

Diff too large to display

Commit: 2151b79

@unstubbable unstubbable force-pushed the hl/use-cache-hanging-inputs-error-handling branch 6 times, most recently from bd2e57a to c61c618 Compare January 10, 2025 14:00
@unstubbable unstubbable force-pushed the hl/use-cache-hanging-inputs-error-handling branch from c61c618 to 837b7de Compare January 14, 2025 18:07
@unstubbable unstubbable force-pushed the hl/use-cache-hanging-inputs-error-handling branch from 837b7de to b980539 Compare January 17, 2025 08:17
@@ -261,22 +268,49 @@ async function collectResult(
}

async function generateCacheEntryImpl(
workStore: WorkStore,
outerWorkUnitStore: WorkUnitStore | undefined,
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this argument always a prerender store? for a nested cache is there a similar timeout we need to observe for the async iterable? would this be a cache store in that case or undefined?

@unstubbable unstubbable force-pushed the hl/use-cache-hanging-inputs-error-handling branch from c8ed464 to caf7b77 Compare January 18, 2025 22:22
Uncached and forever hanging promises are currently not supported as
input for `"use cache"` functions. One prominent example of this is the
use of `searchParams` in a page with `"use cache"`. Until Next.js
version 15.1.1, the usage of such inputs led to an error during build
after a timeout of 50 seconds. This behaviour relied on a bug in
`decodeReply` though, and was hence broken after React fixed the bug. A
build will now fail early with `Error: Connection closed.`.

With this PR, we are restoring the timeout error behaviour by switching
to the new `decodeReplyFromAsyncIterable` API, which allows us to keep
an open stream when decoding the cached function's arguments.

In addition, in dev mode, we are now also propagating the error to the
dev overlay.
@unstubbable unstubbable force-pushed the hl/use-cache-hanging-inputs-error-handling branch from caf7b77 to 2151b79 Compare January 21, 2025 11:12
@unstubbable unstubbable merged commit 338eb99 into canary Jan 22, 2025
135 checks passed
@unstubbable unstubbable deleted the hl/use-cache-hanging-inputs-error-handling branch January 22, 2025 21:39
unstubbable added a commit that referenced this pull request Jan 22, 2025
Based on #74652, this adds error handling for `"use cache"` closures
that use closed-over hanging promises. It uses a similar technique to
encode the hanging promises into the serialized bound arguments string.
In addition, we need to notify the cache signal when decrypting the
bound args, since this operation does not resolve in the current task.
This is now the same behavior as for encrypting the bound args (see
#73521).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants