GuillaumeExia
GuillaumeExia

Reputation: 11

AWS Lambda function global variables

I am writing an AWS Lambda function in JavaScript (Node.js) that interacts with CodeCommit through the AWS SDK.

The communication between the services works as expected, I am getting data within the CodeCommit function, but the issue I am facing appears when I want to use this data outside of the function.

I have tried two approaches:

1. Global Variable

Code:

var aws = require('aws-sdk');
var codecommit = new aws.CodeCommit({ apiVersion: '2015-04-13' });
var repoName = ''; // Declared my global variable here

exports.handler = function(event, context) {
    
    var commitId = "69a5f8eeba340d71ba41b8f20d77cc20b301ff52"
    var repository = "my-repository"
    
    var params = {
        repositoryName: repository
    };
    codecommit.getRepository(params, function(err, data) {
        if (err) {
            console.log(err);
            var message = "Error getting repository metadata for repository " + repository;
            console.log(message);
            context.fail(message);
        } else {
            console.log('Repository Name:', data.repositoryMetadata.repositoryName); // Shown with data
            repoName = data.repositoryMetadata.repositoryName; // Setting the variable
            console.log('Account Id:', data.repositoryMetadata.accountId); // Shown with data
        }
    });
    
    console.log(repoName); // Shown as blank in the output
};

Output:
The last written "console.log" is the first to print in the execution results, but shows blank. The two other console.log (within the functions) are then printed, and they show the data.

2. Function

Code:

var aws = require('aws-sdk');
var codecommit = new aws.CodeCommit({ apiVersion: '2015-04-13' });

exports.handler = function(event, context) {
    
    var commitId = "69a5f8eeba340d71ba41b8f20d77cc20b301ff52"
    var repository = "my-repository"
    
    var repoData = getRepository(repository)
    
    console.log('Repository Name:', repoData.repositoryName);
    console.log('Account Id:', repoData.accountId);
};

function getRepository(repository) {
    var params = {
        repositoryName: repository
    };
    codecommit.getRepository(params, function(err, data) {
        if (err) {
            console.log(err);
            var message = "Error getting repository metadata for repository " + repository;
            console.log(message);
            context.fail(message);
        } else {
            var repoData = {};
            repoData.repositoryName = data.repositoryMetadata.repositoryName;
            repoData.accountId = data.repositoryMetadata.accountId;
            console.log(repoData); // Shows output in execution results when lines 11 & 12 are commented
            return repoData;
        }
    });
}

Output:

{
  "errorType": "TypeError",
  "errorMessage": "Cannot read property 'repositoryName' of undefined",
  "trace": [
    "TypeError: Cannot read property 'repositoryName' of undefined",
    "    at Runtime.exports.handler (/var/task/index.js:57:46)",
    "    at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
  ]
}

Conclusion
None of those approaches worked. The data is always visible within the function but never outside of it. I suspect that the code outside of the function executes before the function itself, and I wonder if I could make the code to wait that the function has been executed before doing the console.log (and other actions after it). Or maybe I am wrong on another level?

Upvotes: 0

Views: 2574

Answers (1)

Jason Wadsworth
Jason Wadsworth

Reputation: 8887

You are using a callback model, in which case the console.log in the first example is being hit before the code in the callback. A better option would be to use async/await.

var aws = require('aws-sdk');
var codecommit = new aws.CodeCommit({ apiVersion: '2015-04-13' });
var repoName = ''; // Declared my global variable here

exports.handler = async function(event, context) {
    
    var commitId = "69a5f8eeba340d71ba41b8f20d77cc20b301ff52"
    var repository = "my-repository"
    
    var params = {
        repositoryName: repository
    };
    var data = await codecommit.getRepository(params).promise();

    console.log('Repository Name:', data.repositoryMetadata.repositoryName); // Shown with data
    repoName = data.repositoryMetadata.repositoryName; // Setting the variable
    console.log('Account Id:', data.repositoryMetadata.accountId); // Shown with data
    
    console.log(repoName);
};

Notice that I'm not catching the error here, but if you wanted to you can use a try/catch block. Just be sure you throw a new error in that case if you want the function to fail.

Upvotes: 1

Related Questions