Next.js应用:用Prisma和Axios获取聊天历史遇500内部服务器错误
问题:Next.js App Router 获取聊天历史时触发500内部服务器错误
场景与现有代码
使用Next.js App Router的[slug]动态路由获取URL中的聊天ID,通过useEffect调用/api/conversation/get接口,尝试从Prisma连接的数据库拉取对应聊天记录,但请求返回500错误。
页面组件(动态路由页面)
export default function ConversationPage({ params, }: { params: { slug: string }; }) { console.log("my slug:", params.slug); useEffect(() => { const fetchData = async () => { const response = await axios.post("/api/conversation/get", { id: params.slug, }); console.log("Conversation data:", response); }; fetchData(); }, [params.slug]); }
API路由(POST请求处理)
export async function POST(req: any) { const { userId } = auth(); if (!userId) { return new NextResponse("Unauthorized", { status: 401 }); } const { id } = req.params; const chatContent = await getConversationHistory(id); return NextResponse.json(chatContent); }
Prisma查询函数
export const getConversationHistory = async (chatId: any) => { const { userId } = auth(); if (!userId) { return false; } try { const conversationHistory = await prismadb.conversationHistory.findUnique({ where: { userId: userId, id: chatId, }, }); if (!conversationHistory) { return false; } return conversationHistory.content; } catch (error) { console.error("Error fetching conversation history:", error); throw error; } finally { await prismadb.$disconnect(); } };
Prisma Schema
model ConversationHistory { id String @id @default(cuid()) userId String label String content Json createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }
错误信息
Object { stack: "AxiosError@webpack-internal:///(app-pages-browser)/./node_modules/axios/lib/core/AxiosError.js:24:19\nsettle@webpack-internal:///(app-pages-browser)/./node_modules/axios/lib/core/settle.js:24:12\nonloadend@webpack-internal:///(app-pages-browser)/./node_modules/axios/lib/adapters/xhr.js:125:66\nEventHandlerNonNull*dispatchXhrRequest@webpack-internal:///(app-pages-browser)/./node_modules/axios/lib/adapters/xhr.js:139:7\n__webpack_exports__.default<@webpack-internal:///(app-pages-browser)/./node_modules/axios/lib/adapters/xhr.js:63:10\ndispatchRequest@webpack-internal:///(app-pages-browser)/./node_modules/axios/lib/core/dispatchRequest.js:61:10\nrequest@webpack-internal:///(app-pages-browser)/./node_modules/axios/lib/core/Axios.js:155:77\nhttpMethod@webpack-internal:///(app-pages-browser)/./node_modules/axios/lib/core/Axios.js:194:19\nwrap@webpack-internal:///(app-pages-browser)/./node_modules/axios/lib/helpers/bind.js:9:15\nfetchData@webpack-internal:///(app-pages-browser)/./app/(dashboard)/(rout…", message: "Request failed with status code 500", name: "AxiosError", code: "ERR_BAD_RESPONSE", config: {…}, request: XMLHttpRequest, response: {…} }
排查与修复步骤
1. 修正API参数获取逻辑
前端通过POST请求体发送id参数,但API错误地从req.params取值,这是核心问题之一。修改API路由代码:
export async function POST(req: any) { const { userId } = auth(); if (!userId) { return new NextResponse("Unauthorized", { status: 401 }); } // 从请求体解析id,而非req.params const { id } = await req.json(); const chatContent = await getConversationHistory(id); return NextResponse.json(chatContent); }
2. 修复Prisma查询的复合约束问题
findUnique仅支持主键或唯一索引字段,原Schema中同时用userId和id作为查询条件,但未定义复合唯一约束,导致查询失败。修改Schema:
model ConversationHistory { id String @id @default(cuid()) userId String label String content Json createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // 添加复合唯一约束,确保userId+id组合唯一 @@unique([userId, id]) }
修改后执行npx prisma migrate dev更新数据库,同时调整查询函数的where条件格式:
const conversationHistory = await prismadb.conversationHistory.findUnique({ where: { userId_id: { // 复合约束的默认命名格式为字段1_字段2 userId: userId, id: chatId, }, }, });
3. 移除Prisma客户端不必要的断开操作
Prisma客户端设计为单例复用,每次请求后调用$disconnect()会导致后续请求无法使用客户端,删除该代码:
// 移除finally块中的以下代码 // await prismadb.$disconnect();
4. 优化错误处理
- 前端添加请求错误捕获,便于调试:
useEffect(() => { const fetchData = async () => { try { const response = await axios.post("/api/conversation/get", { id: params.slug, }); console.log("Conversation data:", response); } catch (err) { console.error("Fetch error:", err.response?.data || err.message); } }; fetchData(); }, [params.slug]);
- API中处理查询结果为空的情况,返回明确的404状态:
export async function POST(req: any) { const { userId } = auth(); if (!userId) { return new NextResponse("Unauthorized", { status: 401 }); } const { id } = await req.json(); const chatContent = await getConversationHistory(id); if (!chatContent) { return new NextResponse("Conversation not found", { status: 404 }); } return NextResponse.json(chatContent); }
内容的提问来源于stack exchange,提问作者Wamz
相关产品推荐
相关产品推荐

