如何在捕获状态下从上一个功能访问步进功能中的错误信息

时间:2019-05-21 14:41:08

标签: python amazon-web-services aws-lambda state-machine aws-step-functions

我想知道如何访问在lambda函数中引发的自定义异常的原因。我需要在“步骤功能”工作流的末尾访问它,如下所示。

下图是执行失败的示例。在error-info的输出中发现了错误(Error对象,带有自己的CauseParseTextractOutput部分),但我想知道如何在{{ 1}},如下所示。

步骤功能图

enter image description here

输出

OutputNotFound的输出是

ParseTextractOutput

我想以某种方式在这些字段(“步骤功能”定义的)中访问此数据:

{
  "event"...
  "error-info": {
    "Error": "OutputNotFoundException",
    "Cause": "{\"errorMessage\": \"Contents of Textracted file: {...}}"
    }
  }
}

Python代码

以下是函数... "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 } 的相关代码。

ParseTextractOutput

1 个答案:

答案 0 :(得分:1)

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

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

这意味着必须在这些声明点之前进行任何处理。正如评论中提到的@frosty一样,Choice状态可能会有用。

替代方法1:使用选择

这里是一个例子:

State machine with choice before fail states

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

class OutputNotFoundException(Exception):
  pass



def lambda_handler(event, context):
    raise OutputNotFoundException('Error message A')

当函数返回时,输出将是这样的JSON:

{
  "Error": "OutputNotFoundException",
  "Cause": "{\"errorMessage\":\"Error message A\",\"errorType\":\"OutputNotFoundException\",\"stackTrace\":[\"...\\n\"]}"
}

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

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

现在我们有这样的输出:

{
  "details": {
    "errorMessage": "Error message A",
    "errorType": "OutputNotFoundException",
    "stackTrace": ["...\n"]
  }
}

下一个状态将是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"
    },

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

    "Error A": {
      "Type": "Fail",
      "Error": "OutputNotFoundException",
      "Cause": "OutputNotFoundException of type A happened"
    },

替代2:以通行证结束

如果您打算将确切的错误消息作为执行的输出以进行以后的日志记录/处理,则一种方法可能会停留在Pass状态:

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

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