3

I have a list of promises invoking other AWS Lambdas from inside an AWS Lambda:

promiseArray.push(lambda.invoke(params).promise())

In another function, I iterate over these promises and try resolve them:

for (let i = 0; i < promiseArray.length; i++) {
    try {
        let result = await promiseArray[i];
        console.log("Success!");
    } catch (e) {
        console.log("Failed!");
    }
}

Here's the issue I'm facing. Often times, the invoke throws a TimeoutError that doesn't get captured by the try-catch block and terminates Lambda execution by throwing an "Unhandled Promise Rejection" error. Note that this started appearing only after we upgraded from Node 8.10 to 12.x on the Lambda.

7
  • Did you try using Promise.all() ? Commented Mar 9, 2020 at 12:05
  • Why don`t you resolve all of them using Promise.all? Commented Mar 9, 2020 at 12:06
  • 1
    I want to resolve each promise separately. If a single promise is rejected, I still want to process the other ones. Commented Mar 9, 2020 at 12:06
  • Can you provide the async function from where these promises are resolved. Commented Mar 9, 2020 at 12:11
  • What's the timeout of this lambda? Is the default 3 seconds? Commented Mar 9, 2020 at 12:12

1 Answer 1

5

The issue lies in the fact the promises are executed immediately after they are created, not when they are awaited upon.

From the Promise documentation:

The executor function is executed immediately by the Promise implementation, passing resolve and reject functions (the executor is called before the Promise constructor even returns the created object)

Considering you are using a custom 1 second timeout, I would say some of these promises are failing even before you reach your loop to wait for them, where you have a try-catch block.

To only run the promises in this try-catch block, you can refactor your code a bit to not create the promise before, but only in the loop. Something along the lines of this:

for (let i = 0; i < params.length; i++) {
    try {
        let result = await lambda.invoke(params[i]).promise();
        console.log("Success!");
    } catch (e) {
        console.log("Failed!");
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. This seems to be the case, explains the intermittent nature of the error. But the above snippet is only as effective as writing synchronous invocation. I'll need to figure how to invoke async while avoiding the original error.
Yes, you are correct. You could use Promise.all to parallelize the invocations, but as you mentioned in a comment, if a single promise fails, you want the others to continue. You can take a look at some answers from here to implement Promise.all without this fail fast behaviour: stackoverflow.com/questions/31424561/…

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.