华为云 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'),初步猜测:
  1. 环境变量缺失
  2. SDK 版本差异
  3. 模块导出被 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"] [] 静态方法被清空
实例方法 完整(withAkwithSk...) 缺失(只剩基础方法) 实例方法被裁剪
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_REGundefined
  • 调用 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. 删除云端云函数,重新上传
 

经验总结

  1. 版本锁定很重要:使用精确版本号,避免自动升级引入 Bug
  2. 本地云端一致性:uniCloud 云端可能使用不同 Node 版本,要注意兼容性
  3. 诊断日志是关键:通过对比本地和云端的环境差异,快速定位问题
  4. SDK Bug 排查:当 tree-shaking 和版本都被排除后,要考虑 SDK 本身的质量问题

参考链接

posted @ 2026-02-03 13:54  三瑞  阅读(4)  评论(0)    收藏  举报