Reputation: 1775
I am trying to create a function on AWS Lambda to send SMS to a mobile phone using Twilio API. I am using Node.JS and mostly followed the instructions in this post here: https://www.twilio.com/blog/aws-lambda-layers-node-js-twilio-sms
The code for sending the SMS which I got from that post is this:
exports.handler = (event, context, callback) => {
// Your Account SID from www.twilio.com/console
// See http://twil.io/secure for important security information
const accountSid = process.env.ACCOUNT_SID;
// Your Auth Token from www.twilio.com/console
// See http://twil.io/secure for important security information
const authToken = process.env.AUTH_TOKEN;
// Import Twilio's Node Helper library
// Create an authenticated Twilio Client instance
const client = require('twilio')(accountSid, authToken);
// Send a text message
client.messages.create({
body: 'Hello from Lambda!',
to: '+12345678901', // your phone number
from: '+12345678901' // a valid Twilio number
})
.then((message) => {
// Success, return message SID
callback(null, message.sid);
})
.catch((e) => {
// Error, return error object
callback(Error(e));
});
};
When I was creating the lambda on AWS I chose a Hello-World template and it had marked the exports.handler callback as async
, like this exports.handler = async (event, context, callback) => {
. I failed to notice this async keyword and copy pasted the method body from that post, ultimately mixing async/await
code with promise style .then
code. I first tested this code locally from my computer and it worked because I just used the method body without any top level function or anything. But when I ran this from AWS Lambda, the environment variables were getting logged correctly, but after that I wasnt getting any other O/P or error. After wasting a lot of time, I decided to change the chained promise style code to async/await style code and it worked. My modified code is this:
exports.handler = async (event, context, callback) => {
// Your Account SID from www.twilio.com/console
// See http://twil.io/secure for important security information
const accountSid = process.env.ACCOUNT_SID;
// Your Auth Token from www.twilio.com/console
// See http://twil.io/secure for important security information
const authToken = process.env.AUTH_TOKEN;
// Import Twilio's Node Helper library
// Create an authenticated Twilio Client instance
const client = require('twilio')(accountSid, authToken);
try {
const messageSid = await client.messages.create({
body: 'Hello from Lambda!',
to: '+12345678901', // your phone number
from: '+12345678901' // a valid Twilio number
});
}
catch(err) {
callback(Error(err));
}
};
My question is, is it wrong to mix async/await with promise type code (.then construct)? If I add async keyword in the 1st line of 1st code it doesnt work. Why does this happen?
Upvotes: 1
Views: 1382
Reputation: 8887
You should not combine the two. Details can be found here: AWS Lambda function handler in Node.js.
One key is this:
For non-async handlers, function execution continues until the event loop is empty or the function times out. The response isn't sent to the invoker until all event loop tasks are finished. If the function times out, an error is returned instead. You can configure the runtime to send the response immediately by setting context.callbackWaitsForEmptyEventLoop to false.
When you are NOT using async
it will wait for the event loop to finish. It does not do this when you are using async
, as it expects you to use async
all the way through.
Upvotes: 1