【问题标题】:AWS Step Function workflow is showing failed status when excutingAWS Step Function 工作流程在执行时显示失败状态
【发布时间】:2021-05-02 07:30:29
【问题描述】:

我正在关注this 教程,以使用 AWS Step Functions 和 AWS Lambda 创建示例工作流。我已经按照博客做了所有事情,但是当我运行它时,它在“Is Case Resolved”阶段显示失败状态。

截图: https://i.stack.imgur.com/ebmbb.png

我做了如下:

Step1:在 AWS 管理控制台中创建了一个角色并复制了角色 ARN 值。

Step2:使用博客中提供的 ASL 代码创建了一个新的状态机,并添加了 Role ARN 值。

Step3:创建了所有 5 个 AWS Lambda 函数

Step4:编辑状态机并添加 Lambda 函数的 Resource 值。

Step5:使用以下代码执行了工作流:

{
    "inputCaseID": "001"
}

我在状态机中的 ASL 代码:

    {
      "Comment": "A simple AWS Step Functions state machine that automates a call center support session.",
      "StartAt": "Open Case",
      "States": {
        "Open Case": {
          "Type": "Task",
          "Resource": "arn:aws:lambda:us-east-2:AccountId:function:OpenCaseFunction",
          "Next": "Assign Case"
        }, 
        "Assign Case": {
          "Type": "Task",
          "Resource": "arn:aws:lambda:us-east-2:AccountId:function:AssignCaseFunction",
          "Next": "Work on Case"
        },
        "Work on Case": {
          "Type": "Task",
          "Resource": "arn:aws:lambda:us-east-2:AccountId:function:WorkOnCaseFunction",
          "Next": "Is Case Resolved"
        },
        "Is Case Resolved": {
            "Type" : "Choice",
            "Choices": [ 
              {
                "Variable": "$.Status",
                "NumericEquals": 1,
                "Next": "Close Case"
              },
              {
                "Variable": "$.Status",
                "NumericEquals": 0,
                "Next": "Escalate Case"
              }
          ]
        },
         "Close Case": {
          "Type": "Task",
          "Resource": "arn:aws:lambda:us-east-2:AccountId:function:CloseCaseFunction",
          "End": true
        },
        "Escalate Case": {
          "Type": "Task",
          "Resource": "arn:aws:lambda:us-east-2:AccountId:function:EscalateCaseFunction",
          "Next": "Fail"
        },
        "Fail": {
          "Type": "Fail",
          "Cause": "Engage Tier 2 Support."    }   
      }
    }

显示错误:

{
  "error": "States.Runtime",
  "cause": "An error occurred while executing the state 'Is Case Resolved' (entered at the event id #17). Invalid path '$.Status': The choice state's condition path references an invalid value."
}

OpenCaseFunction

exports.handler = (event, context, callback) => {
    // Create a support case using the input as the case ID, then return a confirmation message   
   var myCaseID = event.inputCaseID;
   var myMessage = "Case " + myCaseID + ": opened...";   
   var result = {Case: myCaseID, Message: myMessage};
   callback(null, result);    
};

AssignCaseFunction

exports.handler = (event, context, callback) => {    
    // Assign the support case and update the status message    
    var myCaseID = event.Case;    
    var myMessage = event.Message + "assigned...";    
    var result = {Case: myCaseID, Message: myMessage};
    callback(null, result);        
};

WorkOnCaseFunction

exports.handler = (event, context, callback) => {    
    // Generate a random number to determine whether the support case has been resolved, then return that value along with the updated message.
    var min = 0;
    var max = 1;    
    var myCaseStatus = Math.floor(Math.random() * (max - min + 1)) + min;
    var myCaseID = event.Case;
    var myMessage = event.Message;
    if (myCaseStatus == 1) {
        // Support case has been resolved    
        myMessage = myMessage + "resolved...";
    } else if (myCaseStatus == 0) {
        // Support case is still open
        myMessage = myMessage + "unresolved...";
    } 
    var result = {Case: myCaseID, Status : myCaseStatus, Message: myMessage};
    callback(null, result); 
};

EscalateCaseFunction

exports.handler = (event, context, callback) => {    
    // Escalate the support case 
    var myCaseID = event.Case;    
    var myCaseStatus = event.Status;    
    var myMessage = event.Message + "escalating.";    
    var result = {Case: myCaseID, Status : myCaseStatus, Message: myMessage};
    callback(null, result);
};

CloseCaseFunction

exports.handler = (event, context, callback) => { 
    // Close the support case    
    var myCaseStatus = event.Status;    
    var myCaseID = event.Case;    
    var myMessage = event.Message + "closed.";    
    var result = {Case: myCaseID, Status : myCaseStatus, Message: myMessage};
    callback(null, result);
};

我缺少什么?

【问题讨论】:

  • Always mask your Account ID。我假设这是一个Express Workflow,所以你可以分享它失败的状态的日志。另外检查名为 function:WorkOnCaseFunction 的 lambda 它返回的内容,因为进一步的选择取决于此函数的输出。
  • @samtoddler 我已经创建了一个标准的工作流程并且 WorkOnCaseFunction 的输出是成功的。 i.stack.imgur.com/7R2Wg.png 我们是否需要为此制定明确的工作流程?
  • @Mathew 检查提到的 lambda 的输出,它是什么?,您可以检查状态的日志以及它被取消的原因。
  • @samtoddler 你能检查一下这个截图吗,i.stack.imgur.com/W2Tel.png
  • @Mattew Pans 如您在共享的屏幕截图中看到的,输入不正确。它应该类似于 this screenshot 中的 Status 字段在 json 中。因此,请检查您的 function:WorkOnCaseFunction 输出并尝试使用指南中提供的代码。

标签: amazon-web-services aws-lambda aws-step-functions


【解决方案1】:

试试这个 - 它运行良好并且经过多次测试。

类似 - 但不同之处在于 Lambda 函数是使用 Java 运行时 API 编写的。它还向您展示了如何从 Lambda 函数调用其他 AWS 服务,例如 Amazon DynamoDB:

Create AWS serverless workflows by using the AWS SDK for Java

【解决方案2】:

命名的WorkOnCaseFunction 没有产生正确的输出,应该类似于下面的结构。

{ Case: '001', Status: 0, Message: 'hellounresolved...' }

它被choice 状态消耗,该状态尝试使用jsonpath $.Status 获取Status

如果它不存在,那么它会出错并取消状态机的进一步执行。

For example:

下面是我的状态机 without DefaultState 用于 Choice 状态,FailSuccess 取决于生成的输出 function:mytestfunction 可以是 01

{
  "Comment": "An example of the Amazon States Language using a choice state.",
  "StartAt": "FirstState",
  "States": {
    "FirstState": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:eu-central-1:1234567890:function:mytestfunction",
      "Next": "ChoiceState"
    },
    "ChoiceState": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.Status",
          "NumericEquals": 1,
          "Next": "Success"
        },
        {
          "Variable": "$.Status",
          "NumericEquals": 0,
          "Next": "Failed"
        }
      ]
    },
    "Success": {
      "Type": "Pass",
      "Comment": "Success",
      "End": true
    },
    "Failed": {
      "Type": "Pass",
      "Comment": "Failed",
      "End": true
    }
  }
}

function:mytestfunction代码

exports.handler = (event, context, callback) => {    
    // Generate a random number to determine whether the support case has been resolved, then return that value along with the updated message.
    var min = 0;
    var max = 1;    
    var myCaseStatus = Math.floor(Math.random() * (max - min + 1)) + min;
    var myCaseID = "001";
    var myMessage = "hello";
    if (myCaseStatus == 1) {
        // Support case has been resolved    
        myMessage = myMessage + "resolved...";
    } else if (myCaseStatus == 0) {
        // Support case is still open
        myMessage = myMessage + "unresolved...";
    } 
    var result = {Case: myCaseID, Status : myCaseStatus, Message: myMessage};
    console.log('result: %s', result);
    callback(null, result); 
};

我刚刚添加了一条log 消息,将返回到stepfunction,另外只是为了测试我制作了messagecase 静态。

这给了我这样的输出

然后这个来自 lambda 的输出被 Choice 状态消耗,它试图从 function:mytestfunction 生成的以下 json 中仅获取 Status

{ Case: '001', Status: 0, Message: 'hellounresolved...' }

现在您可以看到名为 WorkOnCaseFunction 的 lambda 出了什么问题。它没有以上述格式生成输出,并且您的状态机出现故障。

【讨论】:

  • 问题中的所有功能码我都加了。您能否快速查看一下并告诉我WorkOnCaseFunction 没有产生正确输出的原因?
  • 你能把console.log('result: %s', result);添加到WorkOnCaseFunction函数并分享CloudWatch的日志输出吗?
  • 我已经添加了控制台,但是从哪里可以看到输出?
  • 我已经清除了目前所有的日志并运行一个新的:以下是日志事件截图,你能看一下吗? i.stack.imgur.com/Sm4Z2.png
猜你喜欢
  • 2020-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-03
相关资源
最近更新 更多