简体   繁体   中英

AWS Node JS Lambda Promise Chain

I have written a lambda to take event data and construct and send an SQS message.

I have since tried converting this lambda so it uses promises, however I keep seeing an error where it says:

TypeError: constructAsset(...).then is not a function
at handler (/var/task/src/index.js:80:10)

Here is my lambda attempt with using promises. I also need to figure out to catch the errors and send that in a callback.

The error happens on this line constructAsset(event)

The lambda is running Node 6.10

'use strict'
var AWS = require('aws-sdk'),
    sqs = new AWS.SQS({region: 'eu-west-1'});

// AWS data
const AWS_ACCOUNT_ID = process.env.aws_account_id;
const AWS_SQS_QUEUE_NAME = process.env.aws_sqs_queue_name;
const AWS_SQS_QUEUE_URL = 'https://sqs.eu-west-1.amazonaws.com/' + AWS_ACCOUNT_ID + '/' + AWS_SQS_QUEUE_NAME;

// Vlaidation schemas
const EVENT_TYPE_VALIDATION = ['foo', 'bar'];
const ASSET_TYPE_VALIDATION = ['foo', 'bar'];
const STRING_MATCH_PATTERN  =  new RegExp("^\/[a-z0-9\-\/]*$");

function buildMessageBody (asset, context) {

    let uri = "api.url" + asset.asset_uri,
        site_name  = asset.site_name,
        event_type = asset.event_type,
        asset_type = asset.asset_type,
        write_time = Date.now();


    let MessageBody = {
        "Message": {
            "event_type": event_type,
            "asset_type": asset_type,
            "write_time": write_time,
            "site_name":  site_name,
            "uri":        uri,
        }
    }

    return MessageBody;
}

function validateAsset (asset) {

    if (!asset.asset_uri || !asset.site_name || !asset.asset_type || !asset.event_type) {
        console.log('error', 'Invalid asset data ', 'Asset: ',  JSON.stringify(asset));
        return false
    }

    EVENT_TYPE_VALIDATION.includes(asset.event_type) ? true : false;

    ASSET_TYPE_VALIDATION.includes(asset.asset_type) ? true : false

    STRING_MATCH_PATTERN.test(asset.asset_uri) ? true : false;

    STRING_MATCH_PATTERN.test(asset.site_name) ? true : false;

    return asset

}

function constructAsset(event) {
    let asset = {
        asset_uri:  event.asset_uri != '' ? event.asset_uri : null,
        site_name:  event.site_name != '' ? event.site_name : null,
        asset_type: event.asset_type != '' ? event.asset_type : null,
        event_type: event.event_type != '' ? event.event_type : null
    }

    return asset
}

function constructSQSParams(asset) {
    let sqsParams = {
        MessageBody: JSON.stringify(asset),
        QueueUrl: AWS_SQS_QUEUE_URL
    };

    return sqsParams
}

function handler (event, context, callback) {

    constructAsset(event)
        .then(validateAsset)
        .then(buildMessageBody)
        .then(constructSQSParams)
        .then(function (sqsParams) {
            sqs.sendMessage(sqsParams, function(err, data) {
                if (err) {
                    console.log('error', 'Message Failed To Send: ', err, ' Asset: ', JSON.stringify(asset));
                    callback('Error: Failed to send message');
                } else {
                    console.log('success', 'MessageId: ' + data.MessageId, ' Asset: ', JSON.stringify(asset));
                    callback(null, 'Success: Message sent');
                }
            })
        })
        .catch(function (error) {
            console.log(error);
            callback(null, error)
        })

}

exports.buildMessageBody = buildMessageBody;
exports.validateAsset = validateAsset;
exports.constructAsset = constructAsset;
exports.constructSQSParams = constructSQSParams;
exports.handler = handler;

You can only call .then on a function if it returns a Promise . If your function is like this -

function constructAsset(event) {
    return new Promise((resolve, reject) => {
        let asset = {
            asset_uri:  event.asset_uri != '' ? event.asset_uri : null,
            site_name:  event.site_name != '' ? event.site_name : null,
            asset_type: event.asset_type != '' ? event.asset_type : null,
            event_type: event.event_type != '' ? event.event_type : null
        }
        resolve(asset);
    });
}

Then you'll be able to call constructAsset(event).then() .

Similar is the case with all your functions. And if your code is not making any async calls then you don't need to use promises.

Read more about promises here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM