3

I am using AWS step function to invoke lambda function like this.

 return stepfunctions.startExecution(params).promise().then((result) => {
      console.log(result);
      console.log(result.output);
      return result;
    })

And result is

{ executionArn: 'arn:aws:states:eu-west-2:695510026694:...........:7c197be6-9dca-4bef-966a-ae9ad327bf23',
  startDate: 2018-07-09T07:35:14.930Z }

But i want the result as output of final lambda function

I am going through https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/StepFunctions.html#sendTaskSuccess-property

There are multible function there i am confused which one could be used to get back result of final lambda function.

Same question is there on stackoverflow Api gateway get output results from step function? i dont want to call any function periodically and keep checking status.Even if i use DescribeExecution function periodically i will only get the status of execution but not the result i wanted. Is there any way or any function which returns promise and is resolved once all the lambda has executed and give back the result

3 Answers 3

3

You can't get back a result from a step function execution in a synchronous way.

Instead of polling the result of the step function on completion send a result to an SNS topic or SQS queue for further processing in the final lambda function or model the whole process in the step function state machine.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Michael that was valuable information, found something where i can subscribe to get the result that makes sense but still i found it hard to programaticaly use it for step function, so i decided to go ahead with periodically watching the status and than send back result on success which i think is easier approach and for sure i don't know which is better approach.
3

After doing some study and looking at various tutorial i realized that this stackoverflow answer Api gateway get output results from step function? gives a easier approach to solve the problem and get final result from step function, yes i am not sure about another approach and how to implement any new answer is always appreciated

This is my code to implement the same approach this might help someone.

 // in function first start step function execution using startExecution()
var params = {
        stateMachineArn: 'some correct ARN',
        input: JSON.stringify(body)
      };
return stepfunctions.startExecution(params).promise().then((result) => {

        var paramsStatus = {
          executionArn: result.executionArn
        };

        var finalResponse =  new Promise(function(resolve,reject){
      var checkStatusOfStepFunction =  setInterval(function(){
//on regular interval keep checking status of step function
            stepfunctions.describeExecution(paramsStatus, function(err, data) {
              console.log('called describeExecution:', data.status);
              if (err){
                clearInterval(checkStatusOfStepFunction);
                 reject(err); 

              }
              else {
                if(data.status !== 'RUNNING'){
// once we get status is not running means step function execution is now finished and we get result as data.output
                  clearInterval(checkStatusOfStepFunction);

                   resolve(data.output);
                }  

              }
            }); 
          },200);
        });


        return finalResponse



      })

1 Comment

For my case, I needed to resolve the promise only if the state function is succeeded. That being said, when the data.status == 'SUCCEEDED', I wanted to resolve the promise. And I did a console.log(data.output) before the line resolve(data.output);. But when I'm invoking the Step Function from Lambda, out of 10 times I'm getting undefined for the console.log(). The cloud watch log showing that no such field as data.output event though the status of the step function is SUCCEEDED. Can you suggest a way through which I can resolve the promise only when the status is SUCCEEDED?
1

To be able to get the result of step function (example: combined gateway & step function). You need to:

1. startExecution,
2. wait for your state machine to finish the execution (to be sure make wait equivalent to timeout of your state machine => wait = TimeoutSeconds of your state machine)
3. call describeExecution with the receive executionArn from startExecution.

Note that startExecution is an async function and it's not waiting for the result.

In my case, I'm using Lambda named init to execute the 3 discussed steps:

Code lambda Init:

const AWS = require('aws-sdk')

exports.handler = async (event) => {

    const stepFunctions = new AWS.StepFunctions();
    const reqBody = event.body || {};

    const params = {
        stateMachineArn: process.en.stateMachineArn,
        input: JSON.stringify(reqBody)
    }

    return stepFunctions.startExecution(params).promise()
        .then(async data => {
            console.log('==> data: ', data)
            await new Promise(r => setTimeout(r, 6000));
            return stepFunctions.describeExecution({ executionArn: data.executionArn }).promise();
        })
        .then(result => {
           return {
                statusCode: 200,
                message: JSON.stringify(result)
            }
        })
        .catch(err => {
            console.error('err: ', err)
            return {
                statusCode: 500,
                message: JSON.stringify({ message: 'facing error' })
            }
        })
}

Code stateMachine Make sure that in your statemachine your returning "ResultPath".


{
  "Comment": "Annoucement validation",
  "StartAt": "contact-validation",
  "Version": "1.0",
  "TimeoutSeconds": 5,
  "States": {
     "contact-validation": {
          "Type": "Task",
          "Resource": "arn:aws:xxxxxxx:function:scam-detection-dev-contact", 
          "ResultPath": "$.res",
          "Next": "WaitSeconds"
    }, 
     "WaitSeconds": { 
       "Type": "Wait",
        "Seconds": 1,
        "Next": "Result"     
     },
    "Result": {
      "Type": "Pass",
       "ResultPath": "$.res",
      "End": true
    }
  }
}

1 Comment

I'm getting a 502 'internal server error', even though the all steps are completed successfully

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.