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

Next.js + tRPC调用OpenAI API时Promise提前解析引发报错

问题分析

核心问题是tRPC useMutation的mutate方法不返回Promise,无法用await直接获取响应。你代码里用await mutate(...)得到的response是undefined,因此触发Cannot read properties of undefined (reading 'data')错误。

另外你提到改用useQuery出现的频繁调用/不调用问题,是因为useQuery是自动触发的,适合查询场景,而调用OpenAI API属于生成内容的写操作,用mutation更匹配场景。

解决方案

有两种正确获取mutation响应的方式:

方式一:用mutateAsync替代mutate

tRPC的useMutation提供了mutateAsync方法,它返回Promise,支持await直接获取响应数据,这是最直接的修改方式:

修改前端调用代码:

const [userInput, setUserInput] = useState("");
const searchBarInputToQuery = api.llm.searchBarInputToQuery.useMutation();

const handleSubmit = async () => {
  props.setIsLoading(true);
  props.setCurrentPage(Pages.RESULTS);
  props.setMessages([{ role: "user", content: userInput }]);
  // 替换mutate为mutateAsync
  const response = await searchBarInputToQuery.mutateAsync({ text: userInput });
  console.log(response);
  // 后端直接返回message对象,无需读取response.data
  props.setMessages([...props.messages, response]);
  props.setIsLoading(false);
};

注意:你的后端mutation直接返回了message对象(即response.data.choices[0]!.message!),所以前端拿到的response就是最终要的消息结构,不需要再访问response.data——这也是你之前代码的额外问题。

方式二:使用onSuccess回调处理响应

如果更倾向于用mutate,可以通过配置onSuccess回调处理结果:

const searchBarInputToQuery = api.llm.searchBarInputToQuery.useMutation({
  onSuccess: (response) => {
    console.log(response);
    props.setMessages([...props.messages, response]);
    props.setIsLoading(false);
  },
});

const handleSubmit = () => {
  props.setIsLoading(true);
  props.setCurrentPage(Pages.RESULTS);
  props.setMessages([{ role: "user", content: userInput }]);
  searchBarInputToQuery.mutate({ text: userInput });
};
关于useQuery的补充说明

你之前尝试useQuery遇到的问题,是因为useQuery默认会随查询键变化自动触发。如果要手动触发查询,可以配置enabled: false后调用refetch():

const { data, refetch } = api.llm.searchBarInputToQuery.useQuery(
  { text: userInput },
  { enabled: false } // 关闭自动触发
);

const handleSubmit = async () => {
  props.setIsLoading(true);
  props.setCurrentPage(Pages.RESULTS);
  props.setMessages([{ role: "user", content: userInput }]);
  await refetch();
  if (data) {
    props.setMessages([...props.messages, data]);
  }
  props.setIsLoading(false);
};

但需注意:调用OpenAI API属于生成新内容的写操作,按照API设计原则,这类操作更适合用mutation而非query,因此优先推荐前面两种mutation方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 11:30:24