Skip to content

Commit 146b06b

Browse files
committed
Add response handling in pages handler
1 parent f05106d commit 146b06b

File tree

20 files changed

+1146
-441
lines changed

20 files changed

+1146
-441
lines changed

packages/next/errors.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -693,9 +693,10 @@
693693
"692": "Expected clientReferenceManifest to be defined.",
694694
"693": "%s must not be used within a client component. Next.js should be preventing %s from being included in client components statically, but did not in this case.",
695695
"694": "createPrerenderPathname was called inside a client component scope.",
696-
"695": "Expected workUnitAsyncStorage to have a store.",
697-
"696": "Next DevTools: Can't dispatch %s in this environment. This is a bug in Next.js",
696+
"695": "Invariant: received non-pages cache entry in pages handler",
697+
"696": "Expected workUnitAsyncStorage to have a store.",
698698
"697": "Next DevTools: Can't render in this environment. This is a bug in Next.js",
699-
"698": "Next DevTools: App Dev Overlay is already mounted. This is a bug in Next.js",
700-
"699": "Next DevTools: Pages Dev Overlay is already mounted. This is a bug in Next.js"
699+
"698": "Next DevTools: Can't dispatch %s in this environment. This is a bug in Next.js",
700+
"699": "Next DevTools: App Dev Overlay is already mounted. This is a bug in Next.js",
701+
"700": "Next DevTools: Pages Dev Overlay is already mounted. This is a bug in Next.js"
701702
}

packages/next/src/build/templates/app-page.ts

Lines changed: 27 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { LoaderTree } from '../../server/lib/app-dir-module'
2-
import type { ServerOnInstrumentationRequestError } from '../../server/app-render/types'
32
import type { IncomingMessage, ServerResponse } from 'node:http'
43

54
import {
@@ -26,12 +25,8 @@ import { createServerModuleMap } from '../../server/app-render/action-utils'
2625
import { normalizeAppPath } from '../../shared/lib/router/utils/app-paths'
2726
import { getIsPossibleServerAction } from '../../server/lib/server-action-request-meta'
2827
import {
29-
RouterServerContextSymbol,
30-
routerServerGlobal,
31-
} from '../../server/lib/router-utils/router-server-context'
32-
import {
33-
NEXT_ROUTER_PREFETCH_HEADER,
3428
RSC_HEADER,
29+
NEXT_ROUTER_PREFETCH_HEADER,
3530
} from '../../client/components/app-router-headers'
3631

3732
// These are injected by the loader afterwards.
@@ -132,49 +127,17 @@ export async function handler(
132127
pageIsDynamic,
133128
buildManifest,
134129
nextFontManifest,
135-
serverFilesManifest,
136130
reactLoadableManifest,
137131
serverActionsManifest,
138132
clientReferenceManifest,
139133
subresourceIntegrityManifest,
140134
prerenderManifest,
141135
isDraftMode,
142136
isOnDemandRevalidate,
137+
routerServerContext,
138+
nextConfig,
143139
} = prepareResult
144140

145-
const routerServerContext =
146-
routerServerGlobal[RouterServerContextSymbol]?.[
147-
process.env.__NEXT_RELATIVE_PROJECT_DIR || ''
148-
]
149-
150-
const onInstrumentationRequestError =
151-
routeModule.instrumentationOnRequestError.bind(routeModule)
152-
153-
const onError: ServerOnInstrumentationRequestError = (
154-
err,
155-
_,
156-
errorContext
157-
) => {
158-
if (routerServerContext?.logErrorWithOriginalStack) {
159-
routerServerContext.logErrorWithOriginalStack(err, 'app-dir')
160-
} else {
161-
console.error(err)
162-
}
163-
return onInstrumentationRequestError(
164-
req,
165-
err,
166-
{
167-
path: req.url || '/',
168-
headers: req.headers,
169-
method: req.method || 'GET',
170-
},
171-
errorContext
172-
)
173-
}
174-
175-
const nextConfig =
176-
routerServerContext?.nextConfig || serverFilesManifest.config
177-
178141
const pathname = parsedUrl.pathname || '/'
179142
const normalizedSrcPage = normalizeAppPath(srcPage)
180143
let isIsr = Boolean(
@@ -311,11 +274,7 @@ export async function handler(
311274
isRevalidate ||
312275
// Otherwise we're checking the user agent to decide if we should
313276
// serve streaming metadata.
314-
shouldServeStreamingMetadata(
315-
userAgent,
316-
// @ts-expect-error update for readonly
317-
nextConfig.htmlLimitedBots
318-
)
277+
shouldServeStreamingMetadata(userAgent, nextConfig.htmlLimitedBots)
319278

320279
if (isHtmlBot && isRoutePPREnabled) {
321280
isIsr = false
@@ -360,22 +319,21 @@ export async function handler(
360319
subresourceIntegrityManifest,
361320
serverActionsManifest,
362321
clientReferenceManifest,
363-
isPossibleServerAction,
364-
isOnDemandRevalidate,
365322
setIsrStatus: routerServerContext?.setIsrStatus,
366323

367324
dir: routeModule.projectDir,
368325
isDraftMode,
369326
isRevalidate,
370327
botType,
328+
isOnDemandRevalidate,
329+
isPossibleServerAction,
371330
assetPrefix: nextConfig.assetPrefix,
372331
nextConfigOutput: nextConfig.output,
373332
crossOrigin: nextConfig.crossOrigin,
374333
trailingSlash: nextConfig.trailingSlash,
375334
previewProps: prerenderManifest.preview,
376335
deploymentId: nextConfig.deploymentId,
377336
enableTainting: nextConfig.experimental.taint,
378-
// @ts-expect-error fix issue with readonly regex object type
379337
htmlLimitedBots: nextConfig.htmlLimitedBots,
380338
devtoolSegmentExplorer:
381339
nextConfig.experimental.devtoolSegmentExplorer,
@@ -385,7 +343,6 @@ export async function handler(
385343
incrementalCache: getRequestMeta(req, 'incrementalCache'),
386344
cacheLifeProfiles: nextConfig.experimental.cacheLife,
387345
basePath: nextConfig.basePath,
388-
// @ts-expect-error fix issue with readonly regex object type
389346
serverActions: nextConfig.experimental.serverActions,
390347

391348
...(isDebugStaticShell || isDebugDynamicAccesses
@@ -419,7 +376,13 @@ export async function handler(
419376
},
420377
onAfterTaskError: () => {},
421378

422-
onInstrumentationRequestError: onError,
379+
onInstrumentationRequestError: (error, _request, errorContext) =>
380+
routeModule.onRequestError(
381+
req,
382+
error,
383+
errorContext,
384+
routerServerContext
385+
),
423386
err: getRequestMeta(req, 'invokeError'),
424387
dev: routeModule.isDev,
425388
},
@@ -512,15 +475,20 @@ export async function handler(
512475
} catch (err) {
513476
// if we aren't wrapped by base-server handle here
514477
if (!activeSpan) {
515-
await onError(err, req, {
516-
routerKind: 'App Router',
517-
routePath: srcPage,
518-
routeType: 'render',
519-
revalidateReason: getRevalidateReason({
520-
isRevalidate,
521-
isOnDemandRevalidate,
522-
}),
523-
})
478+
await routeModule.onRequestError(
479+
req,
480+
err,
481+
{
482+
routerKind: 'App Router',
483+
routePath: srcPage,
484+
routeType: 'render',
485+
revalidateReason: getRevalidateReason({
486+
isRevalidate,
487+
isOnDemandRevalidate,
488+
}),
489+
},
490+
routerServerContext
491+
)
524492
}
525493

526494
// rethrow so that we can handle serving error page

packages/next/src/build/templates/app-route.ts

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,6 @@ import {
55
} from '../../server/route-modules/app-route/module.compiled'
66
import { RouteKind } from '../../server/route-kind'
77
import { patchFetch as _patchFetch } from '../../server/lib/patch-fetch'
8-
9-
import * as userland from 'VAR_USERLAND'
10-
import {
11-
RouterServerContextSymbol,
12-
routerServerGlobal,
13-
} from '../../server/lib/router-utils/router-server-context'
148
import type { IncomingMessage, ServerResponse } from 'node:http'
159
import { getRequestMeta } from '../../server/request-meta'
1610
import { getTracer, type Span, SpanKind } from '../../server/lib/trace/tracer'
@@ -31,6 +25,8 @@ import {
3125
type ResponseCacheEntry,
3226
} from '../../server/response-cache'
3327

28+
import * as userland from 'VAR_USERLAND'
29+
3430
// These are injected by the loader afterwards. This is injected as a variable
3531
// instead of a replacement because this could also be `undefined` instead of
3632
// an empty string.
@@ -112,16 +108,12 @@ export async function handler(
112108
buildId,
113109
params,
114110
parsedUrl,
115-
serverFilesManifest,
111+
nextConfig,
116112
prerenderManifest,
113+
routerServerContext,
117114
isOnDemandRevalidate,
118115
} = prepareResult
119116

120-
const routerServerContext =
121-
routerServerGlobal[RouterServerContextSymbol]?.[
122-
process.env.__NEXT_RELATIVE_PROJECT_DIR || ''
123-
]
124-
125117
const onInstrumentationRequestError =
126118
routeModule.instrumentationOnRequestError.bind(routeModule)
127119

@@ -147,9 +139,6 @@ export async function handler(
147139
)
148140
}
149141

150-
const nextConfig =
151-
routerServerContext?.nextConfig || serverFilesManifest.config
152-
153142
const pathname = parsedUrl.pathname || '/'
154143
const normalizedSrcPage = normalizeAppPath(srcPage)
155144
let isIsr = Boolean(

0 commit comments

Comments
 (0)