Node20x运行时Lambda在Step Functions中异常格式不符致重试失效
解决方案:让Node20x Lambda抛出的异常被Step Functions重试机制正确识别
核心问题原因
Node.js 20x运行时中,AWS Lambda的错误序列化逻辑对非标准Error实例的处理更严格:
- 旧的自定义错误构造方式(直接将原型链赋值为
new Error())会被识别为object类型,导致errorType字段变为"object" - 未正确修复原型链的class继承Error方式,也会触发同样的序列化异常
Step Functions的重试规则依赖errorType字段匹配错误名称,因此无法识别这类异常。
可行的修复方案
方案1:使用标准Error实例并手动设置name(最稳妥,兼容所有Node版本)
直接创建标准Error对象,手动指定name为你的自定义错误名称,Lambda序列化时会自动将errorType设为该name值:
// 封装抛出自定义异常的函数 const throwUnreachableServerError = (message) => { const err = new Error(message); err.name = 'UnreachableServerException'; // 必须与Step Functions重试规则中的名称一致 throw err; }; // 使用示例 throwUnreachableServerError('connect ETIMEDOUT XX.XXX.XX.41:443');
方案2:修复class继承Error的原型链
如果坚持使用class定义自定义错误,需要明确设置原型链并指定name属性:
class UnreachableServerException extends Error { constructor(message) { super(message); this.name = 'UnreachableServerException'; // 匹配Step Functions的错误名称 // 修复原型链,确保Node.js和Lambda能正确识别错误类型 Object.setPrototypeOf(this, UnreachableServerException.prototype); } } // 使用示例 throw new UnreachableServerException('connect ETIMEDOUT XX.XXX.XX.41:443');
方案3:修复旧的构造函数式错误定义的原型链
如果需要保留旧的函数式错误定义,修正原型链并添加堆栈捕获:
function UnreachableServerException(message) { this.name = 'UnreachableServerException'; this.message = message; // 捕获堆栈跟踪,同时让错误对象继承Error的原型方法 Error.captureStackTrace(this, UnreachableServerException); } // 正确设置原型链,替代原来的`UnreachableServerException.prototype = new Error()` Object.setPrototypeOf(UnreachableServerException.prototype, Error.prototype); // 使用示例 throw new UnreachableServerException('connect ETIMEDOUT XX.XXX.XX.41:443');
验证效果
使用上述任一方案后,Node20x Lambda抛出的错误序列化后会恢复为Node18x的格式:
{ "errorType": "UnreachableServerException", "errorMessage": "connect ETIMEDOUT XX.XXX.XX.41:443", "trace": [/* 堆栈跟踪内容 */] }
此时Step Functions的重试规则会正确匹配UnreachableServerException,触发对应的重试逻辑。
内容的提问来源于stack exchange,提问作者wiredmartian
相关产品推荐
相关产品推荐

