Skip to content

Commit

Permalink
Fix missing trace file and unhandledRejection in ensurePage (#55553)
Browse files Browse the repository at this point in the history
Seems we occasionally have unhandledRejections with `ensurePage` due to
the our memoize handling not attaching `.catch` quick enough. This
updates to ensure `.catch()` is always present for that promise and
re-throwing separately.

Also, ensures the necessary `module.compiled` files for `route-modules`
are included in our build traces.

x-ref: [slack
thread](https://vercel.slack.com/archives/C04KC8A53T7/p1695072157528389?thread_ts=1695060035.024789&cid=C04KC8A53T7)
  • Loading branch information
ijjk committed Sep 18, 2023
1 parent b5beb3a commit 6123a97
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 16 deletions.
13 changes: 8 additions & 5 deletions packages/next/src/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2269,12 +2269,13 @@ export default async function build(
const moduleTypes = ['app-page', 'pages']

for (const type of moduleTypes) {
const modulePath = require.resolve(
`next/dist/server/future/route-modules/${type}/module.compiled`
)
const relativeModulePath = path.relative(root, modulePath)

const contextDir = path.join(
path.dirname(
require.resolve(
`next/dist/server/future/route-modules/${type}/module`
)
),
path.dirname(modulePath),
'vendored',
'contexts'
)
Expand All @@ -2287,6 +2288,8 @@ export default async function build(
addToTracedFiles(root, itemPath, tracedFiles)
addToTracedFiles(root, itemPath, minimalTracedFiles)
}
addToTracedFiles(root, relativeModulePath, tracedFiles)
addToTracedFiles(root, relativeModulePath, minimalTracedFiles)
}

await Promise.all([
Expand Down
8 changes: 6 additions & 2 deletions packages/next/src/server/dev/hot-reloader-webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1487,12 +1487,16 @@ export default class HotReloader implements NextJsHotReloaderInterface {
if (error) {
return Promise.reject(error)
}
return this.onDemandEntries?.ensurePage({
const res = (await this.onDemandEntries?.ensurePage({
page,
clientOnly,
appPaths,
match,
isApp,
}) as any
})) as any

if (res && res.err) {
throw res.err
}
}
}
35 changes: 26 additions & 9 deletions packages/next/src/server/dev/on-demand-entry-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -726,9 +726,12 @@ export function onDemandEntryHandler({
const isInsideAppDir =
!!appDir && pagePathData.absolutePagePath.startsWith(appDir)

if (typeof isApp === 'boolean' && !(isApp === isInsideAppDir)) {
if (typeof isApp === 'boolean' && isApp !== isInsideAppDir) {
Error.stackTraceLimit = 15
throw new Error(
'Ensure bailed, found path does not match ensure type (pages/app)'
`Ensure bailed, found path "${
pagePathData.page
}" does not match ensure type (${isApp ? 'app' : 'pages'})`
)
}

Expand Down Expand Up @@ -896,7 +899,7 @@ export function onDemandEntryHandler({
}

// Make sure that we won't have multiple invalidations ongoing concurrently.
const curEnsurePage = new Map<string, Promise<void>>()
const curEnsurePage = new Map<string, Promise<void | { err: Error }>>()

return {
async ensurePage({
Expand All @@ -912,21 +915,35 @@ export function onDemandEntryHandler({
match?: RouteMatch
isApp?: boolean
}) {
if (curEnsurePage.has(page)) {
return curEnsurePage.get(page)
const ensureKey = JSON.stringify({ page, clientOnly, match, appPaths })
const pendingEnsure = curEnsurePage.get(ensureKey)

if (pendingEnsure) {
const res = await pendingEnsure

if (res && res.err) {
throw res.err
}
}

const promise = ensurePageImpl({
page,
clientOnly,
appPaths,
match,
isApp,
}).finally(() => {
curEnsurePage.delete(page)
// we have to catch the error since we are memoizing
// otherwise we can hit random unhandledRejections
})
curEnsurePage.set(page, promise)
.catch((err) => {
return { err }
})
.finally(() => {
curEnsurePage.delete(ensureKey)
})

await promise
curEnsurePage.set(ensureKey, promise)
return promise
},
onHMR(client: ws, getHmrServerError: () => Error | null) {
let bufferedHmrServerError: Error | null = null
Expand Down

0 comments on commit 6123a97

Please sign in to comment.