Reputation: 1091
I have the following node code
'use strict';
var aws = require('aws-sdk');
var async = require('async');
const mysql = require('mysql');
var ses = new aws.SES({
region: 'eu-west-1'
});
module.exports.helloWorld = function(event, context, callback) {
//context.callbackWaitsForEmptyEventLoop = false; //Updated on @dashmug recommendation
console.log("Hit here 1");
let connection = mysql.createConnection({
host: "xxx",
user: "xxx",
password: "xxx",
database: "xxx"
});
connection.connect(); //Updated on @dashmug recommendation
console.log("Hit here 2");
connection.query(`SELECT * FROM User U WHERE id = 1`, function(error, row) {
console.log("Hit here 3");
console.log(row);
let eParams = {
Destination: {
ToAddresses: [row[0].email]
},
Message: {
Body: {
Html: {
Data: "Test"
},
Text: {
Data: "Test"
}
},
Subject: {
Data: "Test Email"
}
},
Source: "[email protected]"
};
console.log("Hit here 4");
connection.end(); //Updated on @dashmug recommendation
console.log('===SENDING EMAIL===');
var email = ses.sendEmail(eParams, function(err, data) {
if(err) {
console.log(err);
//context.fail(err);
callback(err); //Updated on @dashmug recommendation
} else {
console.log("===EMAIL SENT===");
console.log("EMAIL CODE END");
console.log('EMAIL: ', email);
console.log(data);
callback(null, event); //Updated on @dashmug recommendation
}
});
});
}
Note: My SES default limits are removed. Also I did try to move connection.end() inside the results callback. I get the same result.
This code always times out. My cloud watch log
{
"errorMessage": "2018-01-19T11:58:16.794Z cc9e6998-fd0f-11e7-ae0a-xxxx Task timed out after 100.06 seconds"
}
START RequestId: e60d142a-01c2-11e8-99da-fb3cb3a59816 Version: $LATEST
2018-01-25T11:28:43.928Z e60d142a-01c2-11e8-99da-fb3cb3a59816 Hit here 1
2018-01-25T11:28:44.163Z e60d142a-01c2-11e8-99da-fb3cb3a59816 Hit here 2
2018-01-25T11:28:44.207Z e60d142a-01c2-11e8-99da-fb3cb3a59816 Hit here 3
2018-01-25T11:28:44.164Z e60d142a-01c2-11e8-99da-fb3cb3a59816 Hit here 4
2018-01-25T11:28:44.209Z e60d142a-01c2-11e8-99da-fb3cb3a59816 [ RowDataPacket {
id: 1,
name: 'Karthik',
email: '[email protected]' } ]
2018-01-25T11:28:44.223Z e60d142a-01c2-11e8-99da-fb3cb3a59816 ===SENDING EMAIL===
END RequestId: e60d142a-01c2-11e8-99da-fb3cb3a59816
REPORT RequestId: e60d142a-01c2-11e8-99da-fb3cb3a59816 Duration: 100038.81 ms Billed Duration: 100000 ms Memory Size: 512 MB Max Memory Used: 54 MB
2018-01-25T11:30:23.965Z e60d142a-01c2-11e8-99da-fb3cb3a59816 Task timed out after 100.04 seconds
My Serverless config.
service: test
provider:
name: aws
runtime: nodejs6.10
stage: dev
region: eu-west-1
memorySize: 512
timeout: 100
iamRoleStatements:
- Effect: Allow
Action:
- s3:*
- SNS:Publish
- SES:SendRawEmail
- SES:SendEmail
- lambda:InvokeFunction
Resource: "*"
environment:
NODE_ENV: live
vpc:
securityGroupIds:
- sg-xxx
- sg-xxx
- sg-xxx
- sg-xxx
subnetIds:
- subnet-xxx
- subnet-xxx
- subnet-xxx
functions:
emailEmailFeedback:
handler: handler.helloWorld
events:
- http:
path: user-feedback
method: get
cors: true
Note: The VPC config is for my MySQL connection. I only have one VPC and all my services are within it.
When I take out the MySQL query and just run my SES test email, the function runs successfully.
Also, when I take the SES out and just run the MySQL I get the results back successfully.
But they don't work together.
I also tried to move the SES to another function and tried to invoke the sendEmail function from inside my MySQL query callback, it didn't work and I get the same timeout error.
lambda.invoke({
FunctionName: 'sendEmail',
Payload: JSON.stringify(rows, null, 2) // pass params
}, function(error, data) {
if (error) {
context.fail({"hello": "world"});
}
if(data.Payload){
context.succeed({"hello": "world"});
}
});
Any help would be much appreciated.
Upvotes: 0
Views: 948
Reputation: 16057
Use callback()
instead of context.succeed()
or context.fail()
. Those context methods are deprecated.
According to https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-using-old-runtime.html#transition-to-new-nodejs-runtime,
Node.js runtime v0.10.42 does not support the callback parameter for your Lambda function that runtimes v4.3 and v6.10 support. When using runtime v0.10.42, you use the following context object methods to properly terminate your Lambda function. The context object supports the done(), succeed(), and fail() methods that you can use to terminate your Lambda function. These methods are also present in runtimes v4.3 and v6.10 for backward compatibility.
So, in your callback for sendMail()
, it becomes...
if(err) {
console.log(err);
callback(err);
} else {
console.log("===EMAIL SENT===");
console.log("EMAIL CODE END");
console.log('EMAIL: ', email);
console.log(data);
callback(null, event);
}
Another thing, you don't need context.callbackWaitsForEmptyEventLoop = false;
.
Also, since you connect to the database inside
your handler, you also need to disconnect from it after you get your results.
Upvotes: 1