如何从 Catch 状态的前一个函数访问 Step Function 中的错误信息

Chu*_*ket 12 python state-machine amazon-web-services aws-lambda aws-step-functions

我想知道如何访问我的 lambda 函数中引发的自定义异常的原因。我需要在 Step Functions 工作流程结束时访问它,如下所示。

下图是执行失败的示例。错误(error-info对象,有它自己ErrorCause部门)的输出被发现ParseTextractOutput,但我想知道如何访问它OutputNotFound,如下图所示。

阶跃函数图

在此处输入图片说明

输出

的输出ParseTextractOutput

{
  "event"...
  "error-info": {
    "Error": "OutputNotFoundException",
    "Cause": "{\"errorMessage\": \"Contents of Textracted file: {...}}"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我想在这些字段(Step Functions 定义)中以某种方式访问​​这些数据:

...
  "States": {
    "OutputNotFound": {
      "Type": "Fail",
      "Error": "<useful stuff here, like $.error-info.Error or something>",
      "Cause": "<useful stuff here, like $.error-info.Cause or something>"
    },
...
    "ParseTextractOutput": {
      "Type": "Task",
      "Resource": "functionARN",
      "Catch": [
        {
          "ErrorEquals": ["OutputNotFoundException"],
          "ResultPath": "$.error-info",
          "Next": "OutputNotFound"
        }
      ],
      "End": true
    }
Run Code Online (Sandbox Code Playgroud)

Python代码

这是 Function 的相关代码ParseTextractOutput

class OutputNotFoundException(Exception):
  pass

...

try:
  blocks = data['Blocks']
except KeyError as e:
  raise OutputNotFoundException('Contents of Textracted file: {}'.format(data))
Run Code Online (Sandbox Code Playgroud)

el_*_*yan 7

目前(使用当前版本的https://states-language.net/spec.htmlFail.Error并且Fail.Cause不能是动态的。传递给状态的输入Fail将被忽略,修复字符串用于错误和原因。

我们可以将其视为Fail执行中的一个点,以宣布修复消息、指示执行结束并出现错误并退出。

这意味着任何处理都必须在这些公告点之前完成。正如 @frosty 在评论中提到的,Choice状态可能很有用。

替代方案 1:使用 Choice

这是一个例子:

在失败状态之前具有选择的状态机

假设我的 Lambda 函数中有以下 Python 代码:

class OutputNotFoundException(Exception):
  pass



def lambda_handler(event, context):
    raise OutputNotFoundException('Error message A')
Run Code Online (Sandbox Code Playgroud)

当函数返回时,输出将是如下 JSON:

{
  "Error": "OutputNotFoundException",
  "Cause": "{\"errorMessage\":\"Error message A\",\"errorType\":\"OutputNotFoundException\",\"stackTrace\":[\"...\\n\"]}"
}
Run Code Online (Sandbox Code Playgroud)

请注意“Cause”是另一个字符串编码的 JSON。我们可以转换OutputNotFoundPass并使用内部函数StringToJson()将编码后的字符串转换为普通的 JSON,以便稍后处理:

    "OutputNotFound": {
      "Type": "Pass",
      "Parameters": {
        "details.$": "States.StringToJson($.Cause)"
      },
      "Next": "Error message?"
    },
Run Code Online (Sandbox Code Playgroud)

现在我们有这样的输出:

{
  "details": {
    "errorMessage": "Error message A",
    "errorType": "OutputNotFoundException",
    "stackTrace": ["...\n"]
  }
}
Run Code Online (Sandbox Code Playgroud)

下一个状态将是一个Choice检查$.details.errorMessage以确定正确的失败状态的状态:

    "Error message?": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.details.errorMessage",
          "StringEquals": "Error message A",
          "Next": "Error A"
        },
        {
          "Variable": "$.details.errorMessage",
          "StringEquals": "Error message B",
          "Next": "Error B"
        }
      ],
      "Default": "Unknown Error"
    },
Run Code Online (Sandbox Code Playgroud)

现在每个选择都指向正常Fail状态以宣布修复字符串:

    "Error A": {
      "Type": "Fail",
      "Error": "OutputNotFoundException",
      "Cause": "OutputNotFoundException of type A happened"
    },
Run Code Online (Sandbox Code Playgroud)

替代方案 2:以通过结束

如果您的目的是将准确的错误消息作为执行的输出以供以后记录/处理,则一种方法可以保留在该Pass状态:

    "OutputNotFound": {
      "Type": "Pass",
      "Parameters": {
        "details.$": "States.StringToJson($.Cause)",
        "isError": true
      },
      "End": true
    }
Run Code Online (Sandbox Code Playgroud)

当然,这个解决方案的缺点是,执行以成功状态结束,我们需要处理输出以发现存在错误(因此isError上面有额外的字段)