1

After going through async/await docs I am still not able to figure out the error in my code. I am trying to do the following when the lambda is invoked.

  1. Log the request object
  2. Do Database Operation
  3. Log the response Object

All of these need to be done in sync.

The below is the code snipped of my logic

    var AWS = require('aws-sdk');
    var lambda = new AWS.Lambda({ region: 'ap-south-1' });
    var mysql = require('/opt/node_modules/mysql');
    var config = require('/opt/config.json');
    var con = mysql.createConnection({
     host: config.dbhost,
     user: config.dbuser,
     password: config.dbpassword,
     database: config.dbname,
    });

exports.handler = async function(event, context, callback) {
    context.callbackWaitsForEmptyEventLoop = false;
    let response = null;
    let errors = [];
    try {
        let body = JSON.parse(event.body);
        const email = body.email;
        const password = body.password;

        let loggerObject = {
            email: email,
            feature: 'LOGIN',
            request: JSON.stringify(body)
        };
        let loggerResponseCallback = await logRequest(loggerObject);
        console.log(loggerResponseCallback);
        const userValidationSQL = `SELECT QUERY`;
        await con.query(userValidationSQL, [email, password], async(userValidationError, userValidationResponse) => {
            if (userValidationError) {
                throw userValidationError;
            }
            console.log(" User Validation Response", userValidationResponse);
            loggerObject = {
                email: email,
                feature: 'LOGIN',
                response: JSON.stringify(userValidationResponse)
            }
            loggerResponseCallback = await logRequest(loggerObject);
            console.log(loggerResponseCallback);
            callback(null, {
                statusCode: 200,
                headers: {
                    "Access-Control-Allow-Origin": "*"
                },
                body: JSON.stringify({ status: 'success', data: userValidationResponse }),
            }) //callback
        })
    }
    catch (error) {
        console.log(" catch========== ", error)
        callback(null, {
            statusCode: 400,
            headers: {
                "Access-Control-Allow-Origin": "*"
            },
            body: JSON.stringify({ status: 'error', message: 'Bad Request', error: errors }),
        })
    }
};



async function logRequest(loggerObject) {
    console.log("Invoking Logger Function");
    let params = {
        FunctionName: 'common-logger',
        InvocationType: 'RequestResponse',
        LogType: 'Tail',
        Payload: JSON.stringify(loggerObject)
    };

    await lambda.invoke(params, function(loggerError, loggerResponse) {
        if (loggerError) {
            console.log("Error in invoking Logger Function ", loggerError)
        }
        console.log('Logger Response:', loggerResponse);
        return loggerResponse;
    });
}

All the combinations of async/await that I try just don't seem to be working. Can someone please guide?

Update II:

With the below code i do manage to get them execute in sequence however i am not able to get the value from the second lambda function

var AWS = require('aws-sdk');
var mysql = require('/opt/node_modules/mysql');
var con = mysql.createConnection({
    host: config.dbhost,
    user: config.dbuser,
    password: config.dbpassword,
    database: config.dbname,
});

exports.handler = function(event, context, callback) {
    context.callbackWaitsForEmptyEventLoop = false;
    let response = null;
    let errors = [];
    try {
        let body = JSON.parse(event.body);
        const email = body.email;
        const password = body.password;
        
        let loggerObject = {
            email: email,
            feature: 'LOGIN',
        };
        let loggerResponseCallback = logRequest(loggerObject);
        console.log('First loggerResponseCallback:', loggerResponseCallback);
        const userValidationSQL = `SELECT Query`;
        con.query(userValidationSQL, [email, password], (userValidationError, userValidationResponse) => {
            if (userValidationError) {
                throw userValidationError;
            }
            console.log(" User Validation Response", userValidationResponse);
            loggerObject = {
                email: email,
                feature: 'LOGIN',
                method: 'POST',
            };
            loggerResponseCallback = logRequest(loggerObject);
            console.log('Second loggerResponseCallback:', loggerResponseCallback);
            callback(null, {
                statusCode: 200,
                headers: {
                    "Access-Control-Allow-Origin": "*"
                },
                body: JSON.stringify({ status: 'success', data: userValidationResponse }),
            }) //callback
        })
    }
    catch (error) {
        console.log(" catch========== ", error)
        callback(null, {
            statusCode: 400,
            headers: {
                "Access-Control-Allow-Origin": "*"
            },
            body: JSON.stringify({ status: 'error', message: 'Bad Request', error: errors }),
        })
    }
};



async function logRequest(loggerObject) {
    var lambda = new AWS.Lambda({ region: 'ap-south-1' });
    console.log("Invoking Logger Function");
    let params = {
        FunctionName: 'common-logger',
        InvocationType: 'RequestResponse',
        LogType: 'Tail',
        Payload: JSON.stringify(loggerObject)
    };
    await lambda.invoke(params, function(loggerError, loggerResponse) {
        if (loggerError) {
            console.log("Error in invoking Logger Function ", loggerError)
        }
        console.log('Logger Response:', loggerResponse);
        return loggerResponse;
    });
}

My Common-Logger Lambda Function

var mysql = require('/opt/node_modules/mysql');
var config = require('/opt/config.json');
var con = mysql.createConnection({
    host: config.dbhost,
    user: config.dbuser,
    password: config.dbpassword,
    database: config.dbname,
});

exports.handler = (event, context, callback) => {
    context.callbackWaitsForEmptyEventLoop = false;
    console.log('invoked logger');
    let loggerId = -1;
    try {
        let email = null,
        
        const sql = 'INSERT QUERY';
        con.query(sql, [ email], (err, res) => {
            if (err) {
                console.log(err)
                throw err;
            }
            loggerId = res.insertId
            console.log('Logger Response:', loggerId);
            if (!correlationID) {
                const sql = 'UPDATE LOGGER SET correlationId = ? WHERE ID = ?';
                con.query(sql, [loggerId, loggerId], (err, res) => {
                    if (err) {
                        console.log(err)
                        throw err;
                    }
                    console.log("Updated CorrelationId for Record:" + loggerId);
                }); //con.query
            }
            callback(null, {
                statusCode: 200,
                headers: {
                    "Access-Control-Allow-Origin": "*"
                },
                body: JSON.stringify({
                    status: 'success',
                    data: { "correlationId": loggerId }
                })
            })
        }); //con.query

    }
    catch (error) {
        console.log("catch", error);
    }
};

Find the AWS Logs attachedenter image description here

4
  • 1
    Don't pass callbacks to asynchronous function when you want to use promises (with async/await). Commented Nov 21, 2020 at 17:55
  • I don't think I am passing any callbacks Commented Nov 21, 2020 at 18:01
  • 1
    con.query(userValidationSQL, [email, password], async(userValidationError, userValidationResponse) => { … }) is passing a callback. Promisify that method so that you can properly await it. Commented Nov 21, 2020 at 18:11
  • Mixing callbacks with async/await reduces readability. Even if you'd have to manually promisify the function, do it. Commented Nov 21, 2020 at 20:38

1 Answer 1

1

I refactored it for you, you can try it:

var AWS = require("aws-sdk");
var lambda = new AWS.Lambda({ region: "ap-south-1" });
var mysql = require("/opt/node_modules/mysql");
var config = require("/opt/config.json");
var con = mysql.createConnection({
  host: config.dbhost,
  user: config.dbuser,
  password: config.dbpassword,
  database: config.dbname,
});

exports.handler = async function (event, context, callback) {
  context.callbackWaitsForEmptyEventLoop = false;
  let response = null;
  let errors = [];

  try {
    let body = JSON.parse(event.body);
    const email = body.email;
    const password = body.password;
    let loggerObject = {
      email: email,
      feature: "LOGIN",
      request: JSON.stringify(body),
    };

    let loggerResponseCallback = await logRequest(loggerObject);
    console.log(loggerResponseCallback);
    const userValidationSQL = `SELECT QUERY`;
    con.query(
      userValidationSQL,
      [email, password],
      async (userValidationError, userValidationResponse) => {
        if (userValidationError) {
          throw userValidationError;
        }
        console.log(" User Validation Response", userValidationResponse);
        loggerObject = {
          email: email,
          feature: "LOGIN",
          response: JSON.stringify(userValidationResponse),
        };
        loggerResponseCallback = await logRequest(loggerObject);
        console.log(loggerResponseCallback);
        callback(null, {
          statusCode: 200,
          headers: {
            "Access-Control-Allow-Origin": "*",
          },
          body: JSON.stringify({
            status: "success",
            data: userValidationResponse,
          }),
        }); //callback
      }
    );
  } catch (error) {
    console.log(" catch========== ", error);
    callback(null, {
      statusCode: 400,
      headers: {
        "Access-Control-Allow-Origin": "*",
      },
      body: JSON.stringify({
        status: "error",
        message: "Bad Request",
        error: errors,
      }),
    });
  }
};

async function logRequest(loggerObject) {
  console.log("Invoking Logger Function");
  let params = {
    FunctionName: "common-logger",
    InvocationType: "RequestResponse",
    LogType: "Tail",
    Payload: JSON.stringify(loggerObject),
  };
  try {
    const loggerResponse = await lambda.invoke(params).promise();
    console.log("Logger Response:", loggerResponse.Payload);
    return loggerResponse.Payload;
  } catch (loggerError) {
    console.log("Error in invoking Logger Function ", loggerError);
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

now i dont see the logger getting invoked nor does my db call gets fired.
Ok sorry I have made a mistake, please try it now.

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.