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

Check for type of route handler returned value at build time (via the TS plugin) and at runtime #51394

Merged
merged 14 commits into from
Sep 8, 2023
Merged
16 changes: 13 additions & 3 deletions packages/next/src/server/future/route-modules/app-route/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ type AppRouteHandlerFnContext = {
}

/**
* Handler function for app routes.
* Handler function for app routes. If a non-Response value is returned, an empty
* 200 response will be used as the HTTP response instead.
*/
export type AppRouteHandlerFn = (
/**
Expand All @@ -80,7 +81,7 @@ export type AppRouteHandlerFn = (
* dynamic route).
*/
ctx: AppRouteHandlerFnContext
) => Promise<Response> | Response
) => unknown

/**
* AppRouteHandlers describes the handlers for app routes that is provided by
Expand Down Expand Up @@ -356,9 +357,18 @@ export class AppRouteRouteModule extends RouteModule<
staticGenerationAsyncStorage:
this.staticGenerationAsyncStorage,
})
const res = await handler(wrappedRequest, {
const rawRes = await handler(wrappedRequest, {
params: context.params,
})
const rawResIsResponse = rawRes instanceof Response
if (!rawResIsResponse) {
Log.warn(
`Route handler ${context.staticGenerationContext.originalPathname} resolved without returning a \`Response\` or a \`NextResponse\``
)
}
const res: Response = rawResIsResponse
? rawRes
: new Response(null)
;(context.staticGenerationContext as any).fetchMetrics =
staticGenerationStore.fetchMetrics

Expand Down