Marcin M
01/04/2022, 10:29 AMconst submitLambda = new Function(this, "SubmitLambda", {
handler: "src/placeOrder/lambdas.submit",
});;
const getStatusLambda = new Function(this, "getStatusLambda", {
handler: "src/placeOrder/lambdas.getStatus",
});;;
const submitJob = new tasks.LambdaInvoke(this, 'Submit Job', {
lambdaFunction: submitLambda,
// Lambda's result is in the attribute `Payload`
outputPath: '$.Payload',
});
const waitX = new sfn.Wait(this, 'Wait X Seconds', {
time: sfn.WaitTime.secondsPath('$.waitSeconds'),
});
const getStatus = new tasks.LambdaInvoke(this, 'Get Job Status', {
lambdaFunction: getStatusLambda,
// Pass just the field named "guid" into the Lambda, put the
// Lambda's result in a field called "status" in the response
inputPath: '$.guid',
outputPath: '$.Payload',
});
const jobFailed = new sfn.Fail(this, 'Job Failed', {
cause: 'AWS Batch Job Failed',
error: 'DescribeJob returned FAILED',
});
const finalStatus = new tasks.LambdaInvoke(this, 'Get Final Job Status', {
lambdaFunction: getStatusLambda,
// Use "guid" field as input
inputPath: '$.guid',
outputPath: '$.Payload',
});
const definition = submitJob
.next(waitX)
.next(getStatus)
.next(new sfn.Choice(this, 'Job Complete?')
// Look at the "status" field
.when(sfn.Condition.stringEquals('$.status', 'FAILED'), jobFailed)
.when(sfn.Condition.stringEquals('$.status', 'SUCCEEDED'), finalStatus)
.otherwise(waitX));
new sfn.StateMachine(this, 'StateMachine', {
definition,
timeout: Duration.minutes(5),
});
it does work, the stateMachine is being deployed to the AWS, i can run it (from AWS) and I see that the exection is correct only if the guid is numeric. those are my lambdas:
export async function submit(event:any) {
console.log("sumbit Lambda", event);
const response = {
statusCode: 200,
headers: { "Content-Type": "text/plain" },
body: `Hello, World! Are we running locally: ${!!process.env.IS_LOCAL}`,
waitSeconds: 1,
guid: '3',
};
return response;
}
export async function getStatus(event:any) {
const status = Math.random() >= 0.5 ? "FAILED" : "SUCCEEDED";
console.log("getStatys Lambda", event, status);
return {
statusCode: 200,
headers: { "Content-Type": "text/plain" },
body: `Hello, World! Are we running locally: ${!!process.env.IS_LOCAL}`,
status: status,
guid: '3',
};
}
and it does work. but if I change the submit lambda to:
export async function submit(event:any) {
console.log("sumbit Lambda", event);
const response = {
statusCode: 200,
headers: { "Content-Type": "text/plain" },
body: `Hello, World! Are we running locally: ${!!process.env.IS_LOCAL}`,
waitSeconds: 1,
guid: 'abc',
};
return response;
}
the difference is guid: 'abc' vs guid: '3'.
I get the following error on the getStatus state
{
"error": "Lambda.InvalidRequestContentException",
"cause": "Could not parse request body into json: Could not parse payload into json: Unrecognized token 'abc': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')\n at [Source: (byte[])\"abc\"; line: 1, column: 4] (Service: AWSLambda; Status Code: 400; Error Code: InvalidRequestContentException; Request ID: 7291da41-1c65-441b-8778-c87602b922cf; Proxy: null)"
}
any idea what may be wrong? I tried different ways of forming the string and all failed which drives me crazy. :DBrinsley
01/04/2022, 10:52 AMJSON.stringify(repsonse)
. Not sure why the string format of your guid
field makes a difference, but maybe it’s falling over further up the stack internally.
Try the stringify method, if it still breaks I’m not quite sure what to suggest.
EDIT: Looking at the docs this seems like a standard thing: https://docs.aws.amazon.com/step-functions/latest/dg/concepts-state-machine-data.html#concepts-state-machine-data-state-input-outputMarcin M
01/04/2022, 10:56 AMexport async function submit(event:any) {
const response = JSON.stringify({
statusCode: 200,
headers: { "Content-Type": "text/plain" },
body: `Hello, World! Are we running locally: ${!!process.env.IS_LOCAL}`,
waitSeconds: 1,
guid: 'abc',
});
return response;
}
then it does not make any change, still failingBrinsley
01/04/2022, 10:58 AMreturn JSON.stringify(response)
is what I meant. You need the string returned by the JSON method.Brinsley
01/04/2022, 10:58 AMFrank
guid
needs to return a JSON object?Frank
guid
was Unrecognized token 'abc': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false'
Brinsley
01/04/2022, 11:00 AMFrank
abc
, so maybe the overall response format is okay.Frank
guid
as an inputPath and step functions want it to be a JSON
inputPath: '$.guid',
Marcin M
01/04/2022, 11:07 AMMarcin M
01/04/2022, 11:13 AMexport async function submit(event:any) {
const status = Math.random() >= 0.5 ? "FAILED" : "SUCCEEDED";
const response = {
statusCode: 200,
headers: { "Content-Type": "text/plain" },
body: `Hello, World! Are we running locally: ${!!process.env.IS_LOCAL}`,
waitSeconds: 1,
guid: { "test" : "abc"},
};
return response;
}
export async function getStatus(event:any) {
const status = Math.random() >= 0.5 ? "FAILED" : "SUCCEEDED";
console.log("getStatys Lambda", event, status);
return {
statusCode: 200,
headers: { "Content-Type": "text/plain" },
body: `Hello, World! Are we running locally: ${!!process.env.IS_LOCAL}`,
status: status,
guid: '3',
};
}
plus important snippets from the statemachine definition:
const submitJob = new tasks.LambdaInvoke(this, 'Submit Job', {
lambdaFunction: submitLambda,
// Lambda's result is in the attribute `Payload`
outputPath: '$.Payload',
});
//..
const getStatus = new tasks.LambdaInvoke(this, 'Get Job Status', {
lambdaFunction: getStatusLambda,
// Pass just the field named "guid" into the Lambda, put the
// Lambda's result in a field called "status" in the response
inputPath: '$.guid',
outputPath: '$.Payload',
});
// ...
const finalStatus = new tasks.LambdaInvoke(this, 'Get Final Job Status', {
lambdaFunction: getStatusLambda,
// Use "guid" field as input
inputPath: '$.guid',
outputPath: '$.Payload',
});
Marcin M
01/04/2022, 11:14 AMFrank
'3'
as an integer instead of a string?Marcin M
01/04/2022, 11:15 AMJSON String, Number, Array, Object or token 'null', 'true' or 'false'
so, how to form just a string? 😄Marcin M
01/04/2022, 11:17 AMguid: true
and then got
{
"error": "States.Runtime",
"cause": "An error occurred while executing the state 'Get Job Status' (entered at the event id #9). The Parameters '{\"FunctionName\":\"arn:aws:lambda:eu-west-1:259471222605:function:e974037-sst-tamos-demo-my--getStatusLambda37FF10F0-nVagaLuMYybZ\",\"Payload\":true}' could not be used to start the Task: [The value for the field 'Payload' must be a STRING]"
}
Frank
Marcin M
01/04/2022, 11:22 AMMarcin M
01/04/2022, 11:23 AM