华为云 IoTDA SDK 报错排查记录:Cannot read properties of undefined (reading 'test')
华为云 IoTDA SDK 报错排查记录:Cannot read properties of undefined (reading 'test')
问题现象
本地运行成功,云端运行失败
表格
| 环境 | 状态 | 错误信息 |
|---|---|---|
| 本地(Node 18.20.0) | ✅ 成功 | 正常查询设备详情 |
| 云端(Node 18.18.2) | ❌ 失败 | TypeError: Cannot read properties of undefined (reading 'test') |
错误堆栈
TypeError: Cannot read properties of undefined (reading 'test')
at BasicCredentials.getDefaultDerivedPredicate [as derivedPredicate]
at BasicCredentials.isDerivedAuth
at BasicCredentials.processAuthRequest
at HcClient.buildRequest
排查过程
第一步:初步判断
根据错误信息
Cannot read properties of undefined (reading 'test'),初步猜测:-
环境变量缺失
-
SDK 版本差异
-
模块导出被 tree-shaking
第二步:添加诊断日志
在
initClient() 函数中添加 SDK 诊断代码,对比本地和云端环境:JavaScript
function initClient() {
console.log('======== SDK 诊断开始 ========');
// 1. 检测 SDK 版本
const corePackage = require('@huaweicloud/huaweicloud-sdk-core/package.json');
console.log('core 版本:', corePackage.version);
// 2. 检测模块导出
const huaweiCore = require('@huaweicloud/huaweicloud-sdk-core');
console.log('BasicCredentials 静态方法:',
Object.getOwnPropertyNames(huaweiCore.BasicCredentials)
.filter(m => typeof huaweiCore.BasicCredentials[m] === 'function')
);
console.log('getDefaultDerivedPredicate 存在:',
'getDefaultDerivedPredicate' in huaweiCore.BasicCredentials
);
// 3. 检测实例方法
const testCreds = new huaweiCore.BasicCredentials();
console.log('实例方法列表:',
Object.getOwnPropertyNames(Object.getPrototypeOf(testCreds))
.filter(m => typeof testCreds[m] === 'function')
);
console.log('======== SDK 诊断结束 ========');
}
第三步:对比本地 vs 云端日志
表格
| 检测项 | 本地(成功) | 云端(失败) | 结论 |
|---|---|---|---|
| core 版本 | 3.1.182 | 3.1.185 | 版本不一致 |
| 静态方法列表 | ["getDefaultDerivedPredicate"] |
[] |
静态方法被清空 |
| 实例方法 | 完整(withAk, withSk...) |
缺失(只剩基础方法) | 实例方法被裁剪 |
| Node.js | v18.20.0 (win32) | v18.18.2 (linux) | 平台不同 |
第四步:验证版本问题
将本地升级到 3.1.185,本地也复现了同样的错误!
说明 3.1.185 版本本身存在 Bug,不是 tree-shaking 问题。
第五步:定位具体 Bug
查看
BaseCredentials.js:106 源码:JavaScript
// 问题代码(推测)
const hostname = new URL(request.endpoint).hostname;
return !BasicCredentials.DEFAULT_ENDPOINT_REG.test(hostname);
错误
Cannot read properties of undefined (reading 'test') 表明:-
BasicCredentials.DEFAULT_ENDPOINT_REG为undefined -
调用
undefined.test()导致报错
根本原因
华为云 SDK 3.1.185 版本存在 Bug:
BasicCredentials.DEFAULT_ENDPOINT_REG 静态属性未正确初始化,导致 getDefaultDerivedPredicate 方法运行时出错。解决方案
方案 1:降级到稳定版本(推荐)
JSON
{
"dependencies": {
"@huaweicloud/huaweicloud-sdk-core": "3.1.182",
"@huaweicloud/huaweicloud-sdk-iotda": "3.1.182"
}
}
方案 2:打补丁修复
JavaScript
// 在文件最顶部添加
const huaweiCore = require('@huaweicloud/huaweicloud-sdk-core');
// 修复 3.1.185 的 Bug
if (!huaweiCore.BasicCredentials.DEFAULT_ENDPOINT_REG) {
huaweiCore.BasicCredentials.DEFAULT_ENDPOINT_REG = /^(iam|iam-pub|iam-my)[-.]/;
}
方案 3:禁用派生认证(绕过)
JavaScript
const credentials = new BasicCredentials()
.withAk(ak)
.withSk(sk)
.withProjectId(projectId);
// 强制禁用派生认证
credentials.derivedPredicate = () => false;
credentials.isDerivedAuth = () => false;
清除缓存彻底降级步骤
bash
# 1. 清除 npm 缓存
npm cache clean --force
# 2. 删除本地依赖
cd uniCloud-alipay/cloudfunctions/iotda-proxy
rd /s /q node_modules
del package-lock.json
# 3. 确保 package.json 锁定版本(无 ^ 前缀)
{
"dependencies": {
"@huaweicloud/huaweicloud-sdk-core": "3.1.182",
"@huaweicloud/huaweicloud-sdk-iotda": "3.1.182"
}
}
# 4. 重新安装
npm install
# 5. 验证版本
npm list @huaweicloud/huaweicloud-sdk-core
# 6. 删除云端云函数,重新上传
经验总结
-
版本锁定很重要:使用精确版本号,避免自动升级引入 Bug
-
本地云端一致性:uniCloud 云端可能使用不同 Node 版本,要注意兼容性
-
诊断日志是关键:通过对比本地和云端的环境差异,快速定位问题
-
SDK Bug 排查:当 tree-shaking 和版本都被排除后,要考虑 SDK 本身的质量问题

浙公网安备 33010602011771号