Next.js+Prisma注册路由报错:payload必须为对象类型
Next.js注册路由报错:"payload"参数必须为对象,接收到null
错误日志
⨯ TypeError: The "payload" argument must be of type object. Received null at AsyncLocalStorage.exit (node:async_hooks:358:14) at POST (./src/app/api/sign-up/route.ts:244:17) ⨯ TypeError: The "payload" argument must be of type object. Received null at frame (node_modules\next\src\server\patch-error-inspect.ts:89:42) at getSourcemappedFrameIfPossible (node_modules\next\src\server\patch-error-inspect.ts:179:32) at parseAndSourceMap (node_modules\next\src\server\patch-error-inspect.ts:234:23) at exit (node_modules\next\src\server\patch-error-inspect.ts:224:32) at apply (webpack://next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js:569:32) at apply (webpack://next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js:593:32) at error (c:\Users\hp\OneDrive\Desktop\Mobile\bridge\src\app\api\sign-up\route.ts:256:16) at async AppRouteRouteModule.do (webpack://next/dist/src/server/route-modules/app-route/module.ts:529:14) at async AppRouteRouteModule.handle (webpack://next/dist/src/server/route-modules/app-route/module.ts:658:30) at async doRender (node_modules\next\src\server\base-server.ts:2504:29) at async responseGenerator (node_modules\next\src\server\base-server.ts:3027:21) at async DevServer.renderToResponseWithComponentsImpl (node_modules\next\src\server\base-server.ts:3039:23) at async DevServer.renderPageComponent (node_modules\next\src\server\base-server.ts:3597:15) at async DevServer.renderToResponseImpl (node_modules\next\src\server\base-server.ts:3659:23) at async DevServer.pipeImpl (node_modules\next\src\server\base-server.ts:1698:20) at async NextNodeServer.handleCatchallRenderRequest (node_modules\next\src\server\next-server.ts:1034:6) at async DevServer.handleRequestImpl (node_modules\next\src\server\base-server.ts:1462:8) at async (node_modules\next\src\server\dev\next-dev-server.ts:514:13) at async Span.traceAsyncFn (node_modules\next\src\trace\trace.ts:143:13) at async DevServer.handleRequest (node_modules\next\src\server\dev\next-dev-server.ts:512:19) at async invokeRender (node_modules\next\src\server\lib\router-server.ts:284:10) at async handleRequest (node_modules\next\src\server\lib\router-server.ts:530:15) at async requestHandlerImpl (node_modules\next\src\server\lib\router-server.ts:576:6) at async Server.requestListener (node_modules\next\src\server\lib\start-server.ts:146:6) 254 | ); 255 | } catch (error) { > 256 | console.error('Error during registration:', error); | ^ 257 | 258 | return new Response( 259 | JSON.stringify({ { code: 'ERR_INVALID_ARG_TYPE' } POST /api/sign-up 500 in 3844ms
问题背景
我在Next.js中开发了一个接收用户名、邮箱、密码的注册接口,使用Prisma操作数据库,要求用户创建后立即发送验证邮件。但运行时持续触发上述错误,测试多种请求payload仍无法解决,怀疑是Prisma相关问题。
相关代码
注册路由代码(src/app/api/sign-up/route.ts)
import bcrypt from 'bcryptjs'; import { PrismaClient } from '@prisma/client'; import { sendVerificationEmail } from '@/helpers/sendVerificationEmail'; const prisma = new PrismaClient(); export async function POST(request: Request) { try { const { username, email, password } = await request.json(); if (!username || !email || !password) { console.log('Missing required fields:', { username, email, password }); return new Response( JSON.stringify({ success: false, message: 'Username, email, and password are required.', }), { status: 400 } ); } const existingUserByUsername = await prisma.user.findFirst({ where: { AND: [{ username }, { isVerified: true }], }, }); if (existingUserByUsername) { console.log('Username already taken:', username); return new Response( JSON.stringify({ success: false, message: 'Username is already taken.', }), { status: 400 } ); } const existingUserByEmail = await prisma.user.findUnique({ where: { email }, }); const verifyCode = Math.floor(10000 + Math.random() * 900000).toString(); const hashedPassword = await bcrypt.hash(password, 10); if (existingUserByEmail) { if (existingUserByEmail.isVerified) { console.log('Email already verified:', email); return new Response( JSON.stringify({ success: false, message: 'User already exists with this email.', }), { status: 400 } ); } console.log('Updating unverified user:', email); const verifyCodeExpiry = new Date(Date.now() + 3600000); await prisma.user.update({ where: { email }, data: { password: hashedPassword, verifyCode, verifyCodeExpiry, }, }); } else { console.log('Creating new user:', { username, email }); const verifyCodeExpiry = new Date(Date.now() + 3600000); await prisma.user.create({ data: { username, email, password: hashedPassword, verifyCode, verifyCodeExpiry, isVerified: false, isAcceptingMessage: true, messages: { create: [], }, }, }); } const emailResponse = await sendVerificationEmail(email, username, verifyCode); console.log('Email response:', emailResponse); if (!emailResponse || !emailResponse.success) { console.log('Failed to send verification email:', emailResponse); return new Response( JSON.stringify({ success: false, message: emailResponse?.message || 'Failed to send verification email.', }), { status: 500 } ); } return new Response( JSON.stringify({ success: true, message: 'User registered successfully. Please verify your email.', }), { status: 200 } ); } catch (error) { console.error('Error during registration:', error); return new Response( JSON.stringify({ success: false, message: 'Error registering user', }), { status: 500 } ); } }
Prisma模型(prisma/schema.prisma)
model Message{ id Int @id @default(autoincrement()) userId Int user User @relation(fields:[userId],references:[id]) content String createdAt DateTime @default(now()) } model User{ id Int @id @default(autoincrement()) username String @unique email String @unique password String verifyCode String verifyCodeExpiry DateTime isVerified Boolean @default(false) isAcceptingMessage Boolean messages Message[] }
解决方案
1. 修复JSON解析错误处理
请求body无效或非JSON格式会导致request.json()返回null,在代码中添加JSON解析的错误捕获:
// 替换原有的request.json()部分 let body; try { body = await request.json(); } catch (e) { return new Response( JSON.stringify({ success: false, message: '请求格式错误,请传递有效的JSON' }), { status: 400, headers: { 'Content-Type': 'application/json' } } ); } const { username, email, password } = body;
2. 优化PrismaClient实例化(避免重复创建)
在src/lib/prisma.ts中创建单例PrismaClient:
import { PrismaClient } from '@prisma/client'; const prisma = global.prisma || new PrismaClient({ log: ['query', 'info', 'warn', 'error'], // 可选,便于调试数据库操作 }); if (process.env.NODE_ENV !== 'production') global.prisma = prisma; export default prisma;
然后在注册路由中替换导入:
// 替换原有的import { PrismaClient } from '@prisma/client';和const prisma = new PrismaClient(); import prisma from '@/lib/prisma';
3. 移除不必要的关联创建代码
创建用户时无需显式创建空的messages数组,Prisma会自动处理关联字段:
// 修改prisma.user.create的data部分,删除messages字段 await prisma.user.create({ data: { username, email, password: hashedPassword, verifyCode, verifyCodeExpiry, isVerified: false, isAcceptingMessage: true, // 移除下面这行 // messages: { create: [] }, }, });
4. 检查验证邮件发送函数
确认sendVerificationEmail内部没有传递null作为需要对象类型的参数,比如邮件服务的请求payload必须是有效对象。例如如果使用Nodemailer,确保mailOptions的所有字段(如to、subject、html)都不为null。
5. 修复语法错误(错误日志中暴露的问题)
错误日志显示JSON.stringify({ { code: 'ERR_INVALID_ARG_TYPE' } })存在语法错误,确保所有JSON.stringify的参数都是合法对象(避免嵌套大括号)。
内容的提问来源于stack exchange,提问作者Ravi
相关产品推荐
相关产品推荐

