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

Node+Express异步代码出现未处理Promise错误与响应头重复发送问题

问题分析与修复方案

你的代码存在两个核心问题:

  • 重复响应客户端:当数据库保存失败时,catch块已发送400响应,但函数后续仍执行到最后的201响应,导致试图在响应已发送后再设置头信息,触发ERR_HTTP_HEADERS_SENT错误。
  • 未处理OpenAI API调用异常:调用OpenAI的两个createCompletion方法时无错误捕获,一旦API调用失败,会抛出未处理的Promise拒绝,触发UnhandledPromiseRejectionWarning。

修复步骤

  1. 统一错误处理流程:将所有异步操作(OpenAI调用、数据库保存)包裹在同一个try/catch块中,确保每个请求只发送一次响应。
  2. 终止错误后的后续执行:在catch块处理错误后用return终止函数,避免重复响应。
  3. 并行优化OpenAI请求:用Promise.all并行执行两个OpenAI请求,提升性能。

修改后的完整代码

const { Configuration, OpenAIApi } = require("openai");

// 创建用户数据
const createUserData = async (req, res) => {
    const { transcript } = req.body; // 移除未使用的id、scores参数
    const user_id = req.user._id;

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

    try {
        // 并行发起两个OpenAI请求,减少总等待时间
        const [feedbackResponse, scoreResponse] = await Promise.all([
            openai.createCompletion({
                model: "text-davinci-002",
                prompt: `Provide personal feedback for me and give me tips: ${transcript}`,
                temperature: 1,
                max_tokens: 200,
                top_p: 1,
                frequency_penalty: 0,
                presence_penalty: 0,
            }),
            openai.createCompletion({
                model: "text-davinci-002",
                prompt: `Give this text a number from 1-100 in terms of positivity: ${transcript}`,
                temperature: 1,
                max_tokens: 100,
                top_p: 1,
                frequency_penalty: 0,
                presence_penalty: 0,
            })
        ]);

        // 清理返回文本的多余空格/换行
        const feedbackText = feedbackResponse.data.choices[0].text.trim();
        const scoreText = scoreResponse.data.choices[0].text.trim();

        const newUserData = new UserData({
            id: 'user',
            scores: scoreText,
            transcript: transcript,
            user_id: user_id,
            feedback: feedbackText
        });

        console.log(newUserData);
        await newUserData.save();

        console.log('POST:', newUserData);
        return res.status(201).json({
            user_data: newUserData,
            feedback: feedbackText,
            score: scoreText
        });
    } catch (error) {
        console.error('请求出错:', error);
        // 统一返回错误响应,终止函数执行
        return res.status(400).json({ error: error.message });
    }
};

额外优化说明

  • 并行处理OpenAI请求,相比原串行执行减少了一半左右的等待时间。
  • 对OpenAI返回的文本做trim()处理,避免多余的空白字符影响数据存储。
  • 移除未使用的参数,简化代码结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 15:05:25