Reputation: 376
I am having trouble with my Lambda function with Serverless framework, which should be putting data to DynamoDB. I'm unsure of the issue as I am getting no error message in the console when I run: sls invoke local -f scrape -d 'the-last-bookstore-los-angeles
.
saveRatingsToDB.js
const uuid = require('uuid');
const AWS = require('aws-sdk');
const dynamoDb = new AWS.DynamoDB.DocumentClient();
module.exports = (data, businessName) => {
console.log('data saving...');
console.log(data);
const params = {
TableName: process.env.DYNAMODB_TABLE,
Item: {
id: uuid.v1(),
businessName: businessName,
reviewCount: data.reviewCount,
rating: data.rating,
createdAt: JSON.stringify(new Date())
}
};
// I am can log params okay, but nothing with dynamoDb.put is logged to the console
dynamoDb.put(params, error => {
console.log('putting data');
if (error) {
console.log(`Error saving data to DynamoDB: ${JSON.stringify(error)}`);
return Promise.reject(
`Error saving data to DynamoDB: ${JSON.stringify(error)}`
);
} else {
console.log('data saved');
return Promise.resolve(params.Item);
}
});
};
handler.js
'use strict';
const { getPage, parsePage, saveRatingsToDB } = require('./utils');
module.exports.scrape = async (event, context) => {
console.log('Function triggered', event);
const name = event;
const page = await getPage(name);
const data = await parsePage(page);
const db = await saveRatingsToDB(data, name);
return db;
};
serverless.yaml
provider:
name: aws
runtime: nodejs8.10
stage: dev
region: eu-west-2
environment:
DYNAMODB_TABLE: my-table-name
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn_reference_"
package:
include:
- utils/**
As mentioned, I get no error message in the console. I can the log and see the params
object from the saveRatingsToDB.js
, but nothing within the actual dynamoDb.put
function.
Any help would be appreciated.
Upvotes: 2
Views: 2051
Reputation: 2522
You tried to run saveRatingsToDB
as an asynchronous function by doing:
const db = await saveRatingsToDB(data, name);
Unfortunately, with the way this function is written currently, it's not an asynchronous function. The reason while you don't see the log inside dynamoDb.put
is because the saveRatingsToDB
function doesn't wait for the asynchronous callback to finish but return earlier.
To make saveRatingsToDB
properly an asynchronous function and force it to wait for the callback, you can return a dynamoDb.put as a promise from that function:
module.exports = (data, businessName) => {
...
// use dynamoDb.put().promise() to return a promise from dynamoDb transaction
return dynamoDb.put(params, error => {
...
// Do whatever with the error
}).promise();
};
Upvotes: 3