diff --git a/packages/next/server/base-server.ts b/packages/next/server/base-server.ts index d3e89af197c7ce0..99b44c8378d8a15 100644 --- a/packages/next/server/base-server.ts +++ b/packages/next/server/base-server.ts @@ -1705,14 +1705,18 @@ export default abstract class Server { let using404Page = false // use static 404 page if available and is 404 response - if (is404) { + if (is404 && (await this.hasPage('/404'))) { result = await this.findPageComponents('/404', query) using404Page = result !== null } let statusPage = `/${res.statusCode}` if (!result && STATIC_STATUS_PAGES.includes(statusPage)) { - result = await this.findPageComponents(statusPage, query) + // skip ensuring /500 in dev mode as it isn't used and the + // dev overlay is used instead + if (statusPage !== '/500' || !this.renderOpts.dev) { + result = await this.findPageComponents(statusPage, query) + } } if (!result) { diff --git a/packages/next/server/dev/on-demand-entry-handler.ts b/packages/next/server/dev/on-demand-entry-handler.ts index 06110c5f42e8d56..00561904706e5be 100644 --- a/packages/next/server/dev/on-demand-entry-handler.ts +++ b/packages/next/server/dev/on-demand-entry-handler.ts @@ -524,123 +524,126 @@ export function onDemandEntryHandler({ ) }, stalledTime * 1000) - const pagePathData = await findPagePathData( - rootDir, - pagesDir, - page, - nextConfig.pageExtensions, - appDir - ) + try { + const pagePathData = await findPagePathData( + rootDir, + pagesDir, + page, + nextConfig.pageExtensions, + appDir + ) + + const isServerComponent = serverComponentRegex.test( + pagePathData.absolutePagePath + ) + const isInsideAppDir = + appDir && pagePathData.absolutePagePath.startsWith(appDir) + + const addEntry = ( + compilerType: CompilerNameValues + ): { + entryKey: string + newEntry: boolean + shouldInvalidate: boolean + } => { + const entryKey = `${compilerType}${pagePathData.page}` + + if (entries[entryKey]) { + entries[entryKey].dispose = false + entries[entryKey].lastActiveTime = Date.now() + if (entries[entryKey].status === BUILT) { + return { + entryKey, + newEntry: false, + shouldInvalidate: false, + } + } - const isServerComponent = serverComponentRegex.test( - pagePathData.absolutePagePath - ) - const isInsideAppDir = - appDir && pagePathData.absolutePagePath.startsWith(appDir) - - const addEntry = ( - compilerType: CompilerNameValues - ): { - entryKey: string - newEntry: boolean - shouldInvalidate: boolean - } => { - const entryKey = `${compilerType}${pagePathData.page}` - - if (entries[entryKey]) { - entries[entryKey].dispose = false - entries[entryKey].lastActiveTime = Date.now() - if (entries[entryKey].status === BUILT) { return { entryKey, newEntry: false, - shouldInvalidate: false, + shouldInvalidate: true, } } + entries[entryKey] = { + type: EntryTypes.ENTRY, + absolutePagePath: pagePathData.absolutePagePath, + request: pagePathData.absolutePagePath, + bundlePath: pagePathData.bundlePath, + dispose: false, + lastActiveTime: Date.now(), + status: ADDED, + } + return { - entryKey, - newEntry: false, + entryKey: entryKey, + newEntry: true, shouldInvalidate: true, } } - entries[entryKey] = { - type: EntryTypes.ENTRY, - absolutePagePath: pagePathData.absolutePagePath, - request: pagePathData.absolutePagePath, - bundlePath: pagePathData.bundlePath, - dispose: false, - lastActiveTime: Date.now(), - status: ADDED, - } + const staticInfo = await getPageStaticInfo({ + pageFilePath: pagePathData.absolutePagePath, + nextConfig, + }) - return { - entryKey: entryKey, - newEntry: true, - shouldInvalidate: true, - } - } + const added = new Map>() - const staticInfo = await getPageStaticInfo({ - pageFilePath: pagePathData.absolutePagePath, - nextConfig, - }) + await runDependingOnPageType({ + page: pagePathData.page, + pageRuntime: staticInfo.runtime, + onClient: () => { + // Skip adding the client entry for app / Server Components. + if (isServerComponent || isInsideAppDir) { + return + } + added.set(COMPILER_NAMES.client, addEntry(COMPILER_NAMES.client)) + }, + onServer: () => { + added.set(COMPILER_NAMES.server, addEntry(COMPILER_NAMES.server)) + }, + onEdgeServer: () => { + added.set( + COMPILER_NAMES.edgeServer, + addEntry(COMPILER_NAMES.edgeServer) + ) + }, + }) - const added = new Map>() + const addedValues = [...added.values()] + const entriesThatShouldBeInvalidated = addedValues.filter( + (entry) => entry.shouldInvalidate + ) + const hasNewEntry = addedValues.some((entry) => entry.newEntry) - await runDependingOnPageType({ - page: pagePathData.page, - pageRuntime: staticInfo.runtime, - onClient: () => { - // Skip adding the client entry for app / Server Components. - if (isServerComponent || isInsideAppDir) { - return - } - added.set(COMPILER_NAMES.client, addEntry(COMPILER_NAMES.client)) - }, - onServer: () => { - added.set(COMPILER_NAMES.server, addEntry(COMPILER_NAMES.server)) - }, - onEdgeServer: () => { - added.set( - COMPILER_NAMES.edgeServer, - addEntry(COMPILER_NAMES.edgeServer) + if (hasNewEntry) { + reportTrigger( + !clientOnly && hasNewEntry + ? `${pagePathData.page} (client and server)` + : pagePathData.page ) - }, - }) - - const addedValues = [...added.values()] - const entriesThatShouldBeInvalidated = addedValues.filter( - (entry) => entry.shouldInvalidate - ) - const hasNewEntry = addedValues.some((entry) => entry.newEntry) - - if (hasNewEntry) { - reportTrigger( - !clientOnly && hasNewEntry - ? `${pagePathData.page} (client and server)` - : pagePathData.page - ) - } + } - if (entriesThatShouldBeInvalidated.length > 0) { - const invalidatePromises = entriesThatShouldBeInvalidated.map( - ({ entryKey }) => { - return new Promise((resolve, reject) => { - doneCallbacks!.once(entryKey, (err: Error) => { - if (err) { - return reject(err) - } - resolve() + if (entriesThatShouldBeInvalidated.length > 0) { + const invalidatePromises = entriesThatShouldBeInvalidated.map( + ({ entryKey }) => { + return new Promise((resolve, reject) => { + doneCallbacks!.once(entryKey, (err: Error) => { + if (err) { + return reject(err) + } + resolve() + }) }) - }) - } - ) - invalidator.invalidate([...added.keys()]) - await Promise.all(invalidatePromises) + } + ) + invalidator.invalidate([...added.keys()]) + await Promise.all(invalidatePromises) + } + } finally { + clearTimeout(stalledEnsureTimeout) } - clearTimeout(stalledEnsureTimeout) }, onHMR(client: ws) {