NodeJS中if/else嵌套分支调用awsCreds函数提示非函数错误问题排查
问题原因说明
该错误和else内部的if/else嵌套完全无关,核心问题是你在函数逻辑中重写了awsCreds变量本身,覆盖了原有的函数引用。
你声明的awsCreds是函数类型变量,但在sts.assumeRole的成功回调中,你执行了以下代码:
awsCreds = { accessKeyId: data.Credentials.AccessKeyId, secretAccessKey: data.Credentials.SecretAccessKey, sessionToken: data.Credentials.SessionToken, cacheExpiration: data.Credentials.Expiration };
第一次调用awsCreds()函数时,这段代码会将原本指向函数的awsCreds变量直接覆盖为普通对象。等到第二次需要刷新凭证再次调用awsCreds()时,awsCreds已经是对象而非函数,自然会抛出「awsCreds is not a function」的错误。
此外你的代码还存在额外逻辑漏洞:全局的cacheExpiration变量从未被主动赋值,第一次调用awsCreds()后该变量仍然是undefined,会导致缓存判断逻辑失效。
修复方案
- 不要用函数同名变量存储凭证结果,单独声明变量存储返回值,同时给全局缓存过期时间赋值:
function awsCreds() { return new Promise((resolve, reject) => { const roleToAssume = { RoleArn: process.env.IAMRole, RoleSessionName: `session1`, DurationSeconds: 900 }; sts.assumeRole(roleToAssume, function(err, data) { if (err) { console.error(err, err.stack); reject(err.stack); } else { // 单独声明变量存储凭证,不覆盖原函数 const credsResult = { accessKeyId: data.Credentials.AccessKeyId, secretAccessKey: data.Credentials.SecretAccessKey, sessionToken: data.Credentials.SessionToken }; // 给全局缓存过期时间赋值 cacheExpiration = data.Credentials.Expiration; resolve(credsResult); } }); }); };
- 为了避免后续再出现类似的变量覆盖问题,可以将函数声明为
const类型,这样发生变量覆盖时会直接抛出语法错误,更早发现问题:
const awsCreds = function() { // 原有函数逻辑 }
内容的提问来源于stack exchange,提问作者JBerto
相关产品推荐
相关产品推荐

