Lambda调用出错时如何向Catch任务传递额外数据?
问题:如何在Step Functions的Catch任务中传递Lambda自定义错误的额外数据
我编写了如下Node.js Lambda函数,抛出包含自定义data字段的CustomError,但在Step Functions的Catch任务输入中,看不到这个data字段。想知道如何将CustomError的data对象传递给Catch任务,或者有没有其他传递额外错误数据的方法。
Lambda函数代码
exports.handler = async (event) => { throw new CustomError('Custom error with data!', { propA: 'A', propB: 'B', }); }; class CustomError extends Error { constructor(message, data) { super(message); this.name = this.constructor.name; this.data = data; // 声明了一个新字段,包含用于其他Lambda函数处理错误的有用数据。 } }
Catch任务的输入示例
{ "Error": "CustomError", "Cause": "{\"errorType\":\"CustomError\",\"errorMessage\":\"Custom error with data!\",\"trace\":[\"CustomError: Cannot list objects\",\" at Runtime.exports.handler (/var/task/index.js:5:11)\",\" at Runtime.handleOnceNonStreaming (/var/runtime/Runtime.js:74:25)\"]}" }
状态机JSON
{ "StartAt": "SomeJob", "States": { "SomeJob": { "Catch": [ { "ErrorEquals": [ "States.ALL" ], "Next": "HandleErrorTask" } ], "End": true, "Type": "Task", "OutputPath": "$.Payload", "Resource": "arn:aws:states:::lambda:invoke", "Parameters": { "FunctionName": "...", "Payload.$": "$" } }, "HandleErrorTask": { "End": true, "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "Parameters": { "FunctionName": "...", "Payload.$": "$" } } }, "TimeoutSeconds": 300 }
解决方案
1. 手动序列化自定义错误,包含data字段
Lambda默认序列化Error对象时,只会保留name、message和stack,不会包含你自定义的data字段。可以手动把完整错误信息(包括data)序列化为JSON字符串,再抛出:
exports.handler = async (event) => { const err = new CustomError('Custom error with data!', { propA: 'A', propB: 'B' }); // 手动构造包含所有字段的错误对象并序列化 throw new Error(JSON.stringify({ errorType: err.name, errorMessage: err.message, data: err.data, trace: err.stack?.split('\n') || [] })); }; class CustomError extends Error { constructor(message, data) { super(message); this.name = this.constructor.name; this.data = data; } }
之后Step Functions的Cause字段会包含这个序列化后的字符串,你可以在HandleErrorTask的Lambda函数里解析Cause,提取data字段。
2. 返回错误格式的成功响应,用Choice状态判断
如果业务允许,不要抛出错误,而是返回一个包含错误标识、信息和自定义数据的成功响应,然后在Step Functions里用Choice状态判断是否需要进入错误处理流程:
修改后的Lambda代码
exports.handler = async (event) => { try { // 模拟业务逻辑出错 throw new CustomError('Custom error with data!', { propA: 'A', propB: 'B' }); } catch (err) { return { success: false, errorType: err.name, errorMessage: err.message, data: err.data }; } }; class CustomError extends Error { constructor(message, data) { super(message); this.name = this.constructor.name; this.data = data; } }
修改后的状态机JSON
{ "StartAt": "SomeJob", "States": { "SomeJob": { "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "Parameters": { "FunctionName": "...", "Payload.$": "$" }, "OutputPath": "$.Payload", "Next": "CheckJobResult" }, "CheckJobResult": { "Type": "Choice", "Choices": [ { "Variable": "$.success", "BooleanEquals": false, "Next": "HandleErrorTask" } ], "Default": "JobSuccess" }, "JobSuccess": { "Type": "Succeed" }, "HandleErrorTask": { "End": true, "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "Parameters": { "FunctionName": "...", "Payload.$": "$" } } }, "TimeoutSeconds": 300 }
这种方式更直观,错误数据可以直接作为任务输出传递到后续步骤,不需要解析序列化字符串。
3. 使用callback模式传递自定义错误(适用于非async函数)
如果使用传统的callback写法,可以把自定义数据附加到错误对象上,虽然Lambda还是会序列化错误,但data字段会被包含在Cause里:
exports.handler = (event, context, callback) => { const err = new CustomError('Custom error with data!', { propA: 'A', propB: 'B' }); callback(err); }; class CustomError extends Error { constructor(message, data) { super(message); this.name = this.constructor.name; this.data = data; } }
同样,需要在HandleErrorTask里解析Cause字符串来获取data。
内容的提问来源于stack exchange,提问作者Andrei Khotko
相关产品推荐
相关产品推荐

