You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Unhandled Rejection (TypeError): 无法读取undefined的‘error’属性问题求助

问题解析与解决方案

让我一步步帮你理清这个问题:

什么是Unhandled Rejection?

Unhandled Rejection(未处理的Promise拒绝)指的是:当一个Promise执行失败(进入reject状态)时,没有任何代码去捕获并处理这个失败。在你的代码里,getmeToken返回了一个Promise,但你在调用它的getToken函数中,只使用了.then()处理成功情况,没有添加.catch()来处理可能的失败,导致Promise的rejection被浏览器视为未处理,从而抛出这个错误。

为什么会出现"Cannot read properties of undefined (reading 'error')"?

这个错误的核心原因有两个:

1. getmeTokencatch块没有返回值

看你的getmeToken函数,当fetch请求失败进入catch时,你只执行了console.log(err),但没有返回任何值。这时候这个Promise的最终结果是undefined。当getToken里的.then()接收到undefined作为info参数时,你尝试访问info.error,自然就会抛出“无法读取undefined的error属性”的错误。

2. 混淆了组件状态的info和回调参数的info

你在useState中定义的info是组件的状态变量,但它和getToken回调里的info参数是完全独立的两个变量!即使状态里初始化了error字段,也不影响回调里的info可能是undefined的情况——这两个变量只是同名而已,没有任何关联。

另外还要注意:你的fetch URL里有个拼写错误payent,应该是payment,这可能是导致请求失败的直接原因之一!

如何修复这个问题?

1. 修复getmeToken的错误处理逻辑

首先修正URL拼写,然后完善fetch的错误处理(因为fetch只有网络错误才会进入catch,服务器返回404/500等错误不会自动reject,需要手动处理),同时在catch里返回一个带error字段的对象,确保上层回调能拿到有效数据:

export const getmeToken = (userId, token) => {
 return fetch(`${API}/payment/gettoken/${userId}`, { // 修正URL拼写错误
 method: "GET",
 headers: {
 Accept: "application/json",
 "Content-Type": "application/json",
 Authorization: `Bearer ${token}`
 }
 }).then(response => {
 // 手动处理非2xx状态码的响应
 if (!response.ok) {
 throw new Error(`请求失败,状态码:${response.status}`);
 }
 return response.json();
 })
 .catch(err => {
 console.log(err);
 // 返回包含error字段的对象,确保上层then能拿到有效值
 return { error: err.message || "获取Token失败,请稍后重试" };
 })
}

2. 在getToken中添加catch处理Unhandled Rejection

同时,建议使用函数式更新状态(避免覆盖之前的状态),并区分状态变量和回调参数(比如把回调参数改名,避免混淆):

const getToken = (userId, token) => {
 // 先更新状态为加载中
 setInfo(prev => ({ ...prev, loading: true, error: "" }));
 
 getmeToken(userId, token).then((responseInfo) => { // 改名避免和状态info混淆
 console.log("INFO COMING", responseInfo);
 if (responseInfo.error) {
 setInfo(prev => ({ ...prev, error: responseInfo.error, loading: false }));
 } else {
 const clientToken = responseInfo.clientToken;
 setInfo(prev => ({ 
 ...prev, 
 clientToken, 
 success: true, 
 loading: false 
 }));
 }
 })
 .catch(err => {
 // 捕获任何未处理的错误,避免Unhandled Rejection
 console.error("获取Token时发生意外错误:", err);
 setInfo(prev => ({ ...prev, error: err.message, loading: false }));
 });
}

3. 额外建议

  • 始终为Promise添加.catch()处理,避免Unhandled Rejection;
  • 区分同名变量,减少代码混淆;
  • 状态更新优先使用函数式更新,尤其是当新状态依赖旧状态时。

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

火山引擎 最新活动