Node.js调用AWS.STS.getSessionToken时SessionToken读取异常求助
嘿,我来帮你拆解这个让人头疼的问题!明明日志里清清楚楚显示Credentials对象有SessionToken,可一单独访问就报错说Cannot read property 'SessionToken' of undefined,这确实挺迷惑的。咱们从几个常见的角度来分析:
最可能的原因:异步错误路径导致credentials变成undefined
你现在的代码混合使用了await和.then/.catch,这会在STS调用失败时埋下隐患:
const credentials = await sts .getSessionToken(params) .promise() .then(data => { return data.Credentials; }) .catch(err => { logger.error('ERROR: ', err); });
当sts.getSessionToken调用失败时,.catch块只打印了错误,但没有返回任何值,这时候credentials就会变成undefined。后续执行logger.debug('Token:', credentials.SessionToken)时,自然会抛出“无法读取undefined的SessionToken属性”的错误。
而你看到的Loaded credentials日志,大概率来自另一次成功的调用,和报错的那次不是同一个执行实例——日志混在一起,让你误以为是同一次执行中Credentials存在但SessionToken无法访问。
解决方案:重构代码,清晰处理成功/失败路径
推荐用try/catch替代混合的await+.then/.catch,这样错误路径更明确,也能避免意外的undefined:
const params = { DurationSeconds: 3600 }; try { // 先获取完整的STS响应 const stsResponse = await sts.getSessionToken(params).promise(); const credentials = stsResponse.Credentials; // 先校验credentials是否存在 if (!credentials) { throw new Error("AWS STS未返回有效凭证"); } logger.debug('Loaded credentials:', credentials); logger.debug('Token:', credentials.SessionToken); return credentials; } catch (err) { logger.error('获取STS凭证失败: ', err); // 重新抛出错误,让上层逻辑处理,或者返回一个默认值(根据你的业务需求) throw err; }
这样做的好处:
- 失败时直接进入
catch块,不会继续执行后续的属性访问代码,避免报错 - 增加了
credentials的存在性校验,就算AWS返回空的Credentials也能提前捕获 - 代码逻辑更清晰,容易追踪每一步的执行路径
额外排查点:区分不同的调用实例
如果你的这个函数被并发调用,成功和失败的日志会混在一起。建议在日志里加上唯一标识(比如请求ID、调用时间戳),这样能快速区分不同的执行实例:
const requestId = Date.now().toString(); // 简单的唯一标识 logger.debug(`[${requestId}] Loaded credentials:`, credentials); logger.debug(`[${requestId}] Token:`, credentials.SessionToken);
这样你就能清楚看到哪条日志对应哪次调用,不会再把成功和失败的日志混淆。
小概率情况:对象序列化的假象
极少数情况下,日志库在序列化对象时可能会显示一些“表面属性”,但实际对象本身并没有这些属性(比如某些代理对象)。不过从你提供的日志来看,Credentials是标准的JSON格式,这种情况可能性极低。
内容的提问来源于stack exchange,提问作者didiz

