Skip to content

Commit 05eda4c

Browse files
committed
refactor: extract getting the action handler into getActionHandler
1 parent 2944692 commit 05eda4c

File tree

2 files changed

+47
-30
lines changed

2 files changed

+47
-30
lines changed

packages/next/errors.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -672,5 +672,6 @@
672672
"671": "Specified images.remotePatterns must have protocol \"http\" or \"https\" received \"%s\".",
673673
"672": "Expected `telemetry` to be set in globals",
674674
"673": "Failed to find Server Action \"%s\". This request might be from an older or newer deployment.%s\\nRead more: https://nextjs.org/docs/messages/failed-to-find-server-action",
675-
"674": "This function cannot be used in the edge runtime"
675+
"674": "This function cannot be used in the edge runtime",
676+
"675": "Action handler not found in action module"
676677
}

packages/next/src/server/app-render/action-handler.ts

+45-29
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,45 @@ export async function handleAction({
866866
}
867867
}
868868

869+
const getActionHandler = async (
870+
// eslint-disable-next-line @typescript-eslint/no-shadow
871+
actionId: string
872+
): Promise<((...args: unknown[]) => Promise<unknown>) | null> => {
873+
// actions.js
874+
// app/page.js
875+
// action worker1
876+
// appRender1
877+
878+
// app/foo/page.js
879+
// action worker2
880+
// appRender
881+
882+
// / -> fire action -> POST / -> appRender1 -> modId for the action file
883+
// /foo -> fire action -> POST /foo -> appRender2 -> modId for the action file
884+
885+
// Validate the actionId.
886+
let actionModId: string
887+
try {
888+
actionModId = getActionModIdOrError(actionId, serverModuleMap)
889+
} catch (err) {
890+
console.error(err)
891+
return null
892+
}
893+
894+
const actionMod = (await ComponentMod.__next_app__.require(
895+
actionModId
896+
)) as Record<string, (...args: unknown[]) => Promise<unknown>>
897+
898+
const actionHandler = actionMod[actionId]
899+
// if the `actionId` is valid, and resolved to a valid `actionModId`, but the module does not contain the action,
900+
// then something went very wrong in the bundling process, and we should error.
901+
if (!actionHandler) {
902+
throw new InvariantError('Action handler not found in action module')
903+
}
904+
905+
return actionHandler
906+
}
907+
869908
try {
870909
return await actionAsyncStorage.run(
871910
{ isAction: true },
@@ -876,15 +915,11 @@ export async function handleAction({
876915

877916
// A fetch action (initiated by the client router).
878917

879-
// Check the action id. if it's not valid, we can bail out immediately.
880-
let actionModId: string
881-
try {
882-
actionModId = getActionModIdOrError(actionId, serverModuleMap)
883-
} catch (err) {
884-
console.error(err)
885-
return {
886-
type: 'not-found',
887-
}
918+
// Get the action function.
919+
const actionHandler = await getActionHandler(actionId)
920+
if (!actionHandler) {
921+
// We didn't recognize the provided actionId, so we can't run the action.
922+
return { type: 'not-found' }
888923
}
889924

890925
// The temporary reference set is used for parsing the arguments and in the catch handler,
@@ -905,26 +940,7 @@ export async function handleAction({
905940
const actionArguments =
906941
await parseFetchActionArguments(temporaryReferences)
907942

908-
// Get the action function.
909-
910-
// actions.js
911-
// app/page.js
912-
// action worker1
913-
// appRender1
914-
915-
// app/foo/page.js
916-
// action worker2
917-
// appRender
918-
919-
// / -> fire action -> POST / -> appRender1 -> modId for the action file
920-
// /foo -> fire action -> POST /foo -> appRender2 -> modId for the action file
921-
922-
const actionMod = (await ComponentMod.__next_app__.require(
923-
actionModId
924-
)) as Record<string, (...args: unknown[]) => Promise<unknown>>
925-
926-
const actionHandler = actionMod[actionId]
927-
943+
// Run the action.
928944
const returnVal = await executeActionAndPrepareForRender(
929945
actionHandler,
930946
actionArguments,

0 commit comments

Comments
 (0)