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. getmeToken的catch块没有返回值
看你的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




