Defer gives an error when running in edge mode in a Next.js app on Vercel
pangolingo opened this issue · comments
I'm attempting to run a Defer function in a Route Handler (formerly called API Route) in my Nextjs app. For performance reasons I marked this API function as using the "edge" runtime instead of the default "nodejs" runtime. This results in an error when I run the function.
Expected behavior:
There are no errors when running a Defer function on the edge runtime.
Actual behavior:
I see an error when running the Defer function. This error occurs in the Next.js app, and the function is never run on Defer's side.
Error: invalid request body: function_name is missing or empty
at (node_modules/@defer/client/esm/httpClient.js:83:18)
at (src/app/api/background-job/route.ts:7:17)
at (node_modules/next/dist/esm/server/future/route-modules/app-route/module.js:189:36) {
code: 'bad_request'
}
Workarounds:
If I change the route back to using the Node.js runtime, it runs without errors
Observations:
The error message appears to indicate that Defer isn't able to figure out the function's name.
Docs for the edge runtime:
https://nextjs.org/docs/app/building-your-application/routing/route-handlers#edge-and-nodejs-runtimes
https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes
Code sample:
This is the Next.js route file - it's pretty simple:
import helloWorld from "@/defer/helloWorld";
export const dynamic = "force-dynamic"; // defaults to auto
export const runtime = "edge"; // 'nodejs' is the default
export async function POST(request: Request) {
const result = await helloWorld("Dave");
console.log("result", result);
return new Response(JSON.stringify({ result }), {
headers: { "Content-Type": "application/json" },
});
}
I suspected that maybe Edge was unable to introspect the function to get the name (see docs here: https://nextjs.org/docs/app/api-reference/edge#unsupported-apis).
But checking in the edge runtime REPL it seems to be able to get the function name just fine.
I enabled debug logs with an ENV variable in Vercel.
When running in the nodejs runtime, I see this log
[defer.run][helloWorld] invoked.
When running in the edge runtime I see this log
[defer.run][] invoked.
Thank you for reporting this to us. It seems that the edge runtime does not support function introspection. We will investigate this issue in more detail and keep you informed.
Could we alter the defer()
function to take a string functionName
in the options? Or is there other introspection going on besides just the name.
In theory adding a functionName
field might resolve 3 problems:
- this issue with the edge runtime not supporting introspection
- requiring the user to turn off experimental
serverMinification
in the Nextjs config - ability to use this library with Deno (since you would no longer have to pass the actual function to
defer()
, you could write the deferred functions in standard Typescript, not Deno code
You are right @pangolingo; your approach would definitely be a good workaround while we make progress on another approach that would conserve our current DX (for example: @defer/client
good behave like Prisma client and generates an artifact of functions' mapping)