2

I am trying to connect an external (not AWS) MySql server from an AWS Lambda function written in Node.js using nodejs14.x environment, but the connect() callback is not called.

I am been struggling with this problem since days, there are a lot of references to similar issues but I really tried all possible permutations of solutions I found.

I am deploying with SAM and testing both on local machine and on real AWS.

Here is the sample code of the lambda helper

    const mysql = require('mysql');

    exports.helloFromLambdaHandler = async () => {

    const message = 'Hello from Lambda!';

    console.info(`${message}`);
    
    var sql = "SELECT 1+? AS sum";
    var values = [1];

    console.log("Doing createConnection");
    const connection = mysql.createConnection({
        /* my connection data */
      });
    
    console.log("Doing connect");
    connection.connect( (err) => {
        console.log("Inside connection callback");
        console.log('connected as id ' + connection.threadId);

        if(!err) {
          console.log("DB connected, thread id is "  + connection.threadId);
          console.log("Doing query");

          connection.query(sql, values, (err, result, values) => {
            console.log("Inside query callback");
            if(!err) {
              console.log("Query ok!");
              console.log(result);
              connection.end();
            } else {
              console.log("Error executing query: " + err.message);
            }       
          });
          
        } else {
          console.log("Error connecting db: "+ err.message);
        }
      });

    console.log ("Returning...");
    return message;
}

The log is

Hello from Lambda!
Doing createConnection
Doing connect
Returning...

The expected behaviour is that after "Returning..." I should see the log "Inside connection callback" then "Inside query callback" and then "Query ok!".

Instead the callback of connect() appears not invoked.

I know that I can call query() directly skipping connect() but also doing so I encounter same issue.

Any clue?

Thank you!

SOLUTION

As suggested by the accepted answer, returning a promise is the solution to let Node complete all the queue. Unfortunately it's not possible to complete the Lambda and leave it running in background in a safe manner, for what I understand.

I am investigating alternative solutions such as:

  • mysql2 library which supports promises natively
  • serverless-mysql npm package which handles shared db connections

Below the running demo code

const mysql = require('mysql');

exports.helloFromLambdaHandler = async (event, context) => {

    const message = 'Hello from Lambda!';

    console.info(`${message}`);
    
    var sql = "SELECT 1+? AS sum";
    var values = [1];

    console.log("Doing createConnection");
    const connection = mysql.createConnection({
        /* my connection data */
      });
    
    console.log("Doing query");

    const promise = new Promise( (resolve, reject) => {
        connection.query(sql, values, (err, result, values) => {
        console.log("Inside query callback");
        if(!err) {
            console.log("Query ok!");
            console.log(result);
            connection.end();
            resolve(message);
        } else {
            console.log("Error executing query: " + err.message);
            reject(err);
        }       
        });
    });

    console.log ("Returning...");
    return promise;
}
2
  • Generally speaking: after you return from the lambda the lambda is done, it does not doy any further work, its memory / disk is frozen until the next lambda invocation. Commented Apr 6, 2021 at 9:27
  • As Marcin response pointed out, that is the behaviour due to the declaring the hander as async! Removing that keyword allowed to process the Node queue after return! :) Commented Apr 6, 2021 at 10:05

1 Answer 1

1

You are using async handler, thus your function probably completes before your connect() has a chance to execute.

To try to overcome the issue, you can use Promise as shown in AWS docs.

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

2 Comments

Thank you! Just removing the keyword async in the handler declaration allowed to have all my node queue processed as expected!! Now I will investigate if I really need the hander as async or not and I will followup accordingly!
A detailed explanation of the issue I was facing is in the link below, thanks again for pointing me in the right direction!!! levelup.gitconnected.com/…

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.