调用OpenAI接口遇500、429及JSON解析错误求助
问题分析与解决方案
错误连锁关系
三个错误是递进触发的:
- 429错误:OpenAI API请求频率超限(或API密钥无效/额度耗尽)
- 500内部服务器错误:后端未捕获OpenAI API的异常,导致服务器崩溃并返回HTML错误页面
- 前端JSON解析错误:前端收到HTML而非预期的JSON响应,调用
response.json()时解析失败
具体修复步骤
1. 处理OpenAI API限流问题
- 检查OpenAI账户的API调用额度与频率限制,确认未超出免费/付费限额
- 可降低
max_tokens参数值、减少单次请求的输出长度,或调整调用频率
2. 后端添加异常捕获逻辑
原代码未处理OpenAI API的调用异常,一旦请求失败会直接抛出错误导致服务器返回500。修改后端代码,添加try-catch捕获异常并返回标准JSON错误响应:
import { Configuration, OpenAIApi } from 'openai'; const configuration = new Configuration({ apiKey: process.env.OPENAI_API_KEY, }); const openai = new OpenAIApi(configuration); const basePromptPrefix = `Create a solidity smart contract for `; const versionUser = " use solidity version 0.8.17"; const chatGPT = async (req, res) => { try { let selectOpenZeppelin = ""; if(req.body.checked) { selectOpenZeppelin = ` Using OpenZeppelin`; } const baseCompletion = await openai.createCompletion({ model: 'text-davinci-003', prompt: `${basePromptPrefix}${req.body.userInput}${selectOpenZeppelin}${versionUser}`, temperature: 0.6, max_tokens: 4000, }); const data_output = baseCompletion.data.choices.pop(); res.status(200).json({ output: data_output }); } catch (error) { // 捕获并返回OpenAI API错误信息 res.status(error.response?.status || 500).json({ error: error.response?.data?.error?.message || '服务器内部错误' }); } }; export default chatGPT;
3. 前端添加响应校验与错误处理
原代码未判断请求是否成功就直接解析JSON,修改后先检查响应状态,再处理错误:
const callGenerateEndpoint = async () => { setApiOutput(`Please Wait ....`); console.log("Calling OpenAI..."); try { const response = await fetch("/api/chatgpt", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ userInput, checked }), }); if (!response.ok) { // 处理非200状态码的错误响应 const errorData = await response.json(); throw new Error(errorData.error || `请求失败: ${response.status}`); } const data = await response.json(); const { output } = data; console.log("OpenAI replied...", output.text); setApiOutputForRemix(output.text); const formattedText = output.text.replace(/\n/g, "<br>"); const sanitizedOutput = sanitizeHtml(formattedText); setApiOutput(`${sanitizedOutput}`); } catch (error) { // 捕获所有错误并更新UI console.error("请求错误:", error); setApiOutput(`请求失败: ${error.message}`); } };
额外注意事项
- 确认环境变量
OPENAI_API_KEY已正确配置且密钥有效 - 若429错误频繁出现,可实现指数退避重试逻辑,避免重复触发限流
- 前端可添加
AbortController实现加载状态的取消,防止重复发送请求
内容的提问来源于stack exchange,提问作者Bartu Bozkurt
相关产品推荐
相关产品推荐

