You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中Axios调用/api/conversation接口返回500错误求助

Next.js + OpenAI API 500内部错误排查方案

问题描述

在Next.js应用中,前端通过Axios向/api/conversation端点发送POST请求时,持续收到Internal Server Error 500响应,错误发生在与OpenAI API交互的环节。

代码展示

前端 page.tsx

"use client";

import * as z from "zod";
import { Heading } from "@/components/heading";

import { MessageSquare } from "lucide-react";
import { useForm } from "react-hook-form";
import { formSchema } from "./constants";
import {zodResolver} from "@hookform/resolvers/zod";
import { Form, FormControl, FormField, FormItem } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import axios from "axios";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { ChatCompletionRequestMessage } from "openai";

const ConversationPage=()=>{
    const router=useRouter();
    const [messages,setMessages]=useState<ChatCompletionRequestMessage[]>([]);
    const form= useForm<z.infer<typeof formSchema>>({
    resolver:zodResolver(formSchema),
        defaultValues:{
            prompt:""
        }
    });

    const isLoading=form.formState.isSubmitting;
    const onSubmit=async(values: z.infer<typeof formSchema>)=>{
        try{
            const userMessage:ChatCompletionRequestMessage={
                role:"user",
                content:values.prompt,
            };
            const newMessages=[...messages,userMessage];
            const response=await axios.post("/api/conversation",{
                messages:newMessages,
            });
            setMessages((current)=>[...current,userMessage,response.data]);
            form.reset();
        } catch(error:any){
            console.log(error)
        } finally{
            router.refresh();
        }
    };
    return(
        
        <div>
            <Heading
            title="Conversation"
            description="Our most advanced conversation model."
            icon={MessageSquare}
            iconColor="text-violet-500"
            bgColor="bg-violet-500/10"
            />
            <div className="px-4 lg:px-8">
                <div>
                    <Form {...form}>
                        <form onSubmit={form.handleSubmit(onSubmit)} className="rounded-lg border w-full p-4 px-3 md:px-6 focus-within:shadow-sm grid grid-cols-12 gap-2">
                        <FormField name="prompt" render={({field})=>(<FormItem className="col-span-12 lg:col-span-10">
                            <FormControl className="m-0 p-0">
                                <Input className="border-0 outline-none
                                focus-visible:ring-0
                                focus-visible:ring-transparent" disabled={isLoading} placeholder="How do i calculate the radius of circle?"{...field}/>
                            </FormControl>
                        </FormItem>)}></FormField>
                        <Button className="col-span-12 lg:col-span-2 w-full" disabled={isLoading}>Generate</Button>
                        </form>

                    </Form>
                </div>
                <div className="space-y-4 mt-4">
                    <div className="flex flex-col-reverse gap-y-4">
                        {messages.map((message)=>(
                            <div key={message.content}>{message.content}
                            </div>
                        ))}
                    </div>
                </div>
            </div>
        </div>
    );
}
export default ConversationPage;

后端 /api/conversation

import { auth } from "@clerk/nextjs";
import { NextResponse } from "next/server";
import { Configuration, OpenAIApi } from "openai";

const configuration=new Configuration({
    apiKey:process.env.OPENAI_API_KEY,
});
const openai=new OpenAIApi(configuration);

export async function POST(
    req:Request
){
    try{
        const {userId}=auth();
        const body=await req.json();
        const {messages}=body;
        if(!userId){
            return new NextResponse("Unauthorized",{status:401});
        }
        if(!configuration.apiKey){
            return new NextResponse("OpenAI API Key not configured",{status:500});
        }
        if (!messages){
            return new NextResponse("Message are required",{status:400});
        }
        const response=await openai.createChatCompletion({
            model:"gpt-3.5-turbo",
            messages
        });
        return NextResponse.json(response.data.choices[0].message);

    }catch(error){
        console.log("[CONVERSATION_ERROR]");
        return new NextResponse("Internal error",{status:500})
    }
}

错误详情

发送Axios POST请求时,浏览器控制台显示:POST http://localhost:3000/api/conversation 500 (Internal Server Error),AxiosError对象提示“Request failed with status code 500”,确认是服务器端返回内部错误。

已执行的排查步骤

  • 检查/api/conversation后端代码逻辑,包括OpenAI请求构造、错误处理和响应逻辑
  • 验证OPENAI_API_KEY环境变量配置正确且后端可读取
  • 确认POST请求格式符合OpenAI API文档要求
  • 在Axios请求环节添加日志,增强前端错误处理

排查与解决建议

1. 完善后端错误日志

当前后端catch块仅打印[CONVERSATION_ERROR],无法定位具体问题。修改代码打印完整错误信息:

catch (error: any) {
  console.log("[CONVERSATION_ERROR]", error);
  return new NextResponse("Internal error", { status: 500 });
}

如果是OpenAI SDK抛出的错误,还可以进一步解析响应:

catch (error: any) {
  if (error.response) {
    // 打印OpenAI返回的具体错误信息
    console.log("[OPENAI_ERROR]", error.response.data);
    return new NextResponse(`OpenAI Error: ${error.response.data.error.message}`, { status: error.response.status });
  } else {
    console.log("[CONVERSATION_ERROR]", error.message);
    return new NextResponse("Internal error", { status: 500 });
  }
}

2. 验证OpenAI API直接可用性

用curl或Postman直接调用OpenAI的Chat Completions接口,使用相同的API Key和messages参数,确认接口本身可正常响应:

curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY" \
  -d '{
    "model": "gpt-3.5-turbo",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'

如果此请求失败,说明问题出在OpenAI端(比如API Key无效、额度耗尽、区域限制等)。

3. 检查请求参数格式

确保前端发送的messages数组完全符合OpenAI要求:每个元素必须包含role(取值为user/assistant/system)和content字段,无多余或缺失字段。可以在前端onSubmit中打印newMessages,或在后端打印收到的messages进行验证。

4. 确认环境变量加载

在后端代码开头添加日志,验证OPENAI_API_KEY是否正确读取:

console.log("OPENAI_API_KEY:", process.env.OPENAI_API_KEY);

注意:Next.js服务启动后修改.env文件需要重启服务才能生效;后端环境变量不需要加NEXT_PUBLIC_前缀,但需确保.env文件位于项目根目录。

5. 检查Clerk认证

如果不需要Clerk认证测试,可以暂时注释掉if(!userId)的判断,排除认证环节导致的错误。


内容的提问来源于stack exchange,提问作者yasith samarasinghe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 18:05:07