Updating a dynamoDB table (incrementing an integer) using transactions in lambda - node.js

I'm trying to update the follower-count for two items in a dynamoDB table using node.js 12.x. Here is my code:
const AWS = require('aws-sdk');
AWS.config.update({region: "us-east-2"});
const dynamoDb = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event) => {
const followingUser = "#FRIEND#"+ event.queryStringParameters.followingUser;
const followedUser = "USER#" + event.queryStringParameters.followedUser;
const followedMetadata = "#METADATA#" + followedUser;
const followingMetadata = "#METADATA#" + followingUser;
const followingUsername = "USER#" + followingUser;
const current_time = Date.now();
console.log(event);
try{
const response = await dynamoDb.transactWrite({
TransactItems: [
{
Put: {
TableName: "rememoriesDBv2",
Item: {
"PK": followedUser,
"SK": followingUser,
"followedUser": event.queryStringParameters.followedUser,
"followingUser": event.queryStringParameters.followingUser,
"timestamp":current_time
},
ConditionExpression: "attribute_not_exists(SK)",
ReturnValuesOnConditionCheckFailure: "ALL_OLD"
}
},
{
Update:{
TableName: "rememoriesDBv2",
Key: { "PK": { "S": followedUser}, "SK": { "S": followedMetadata} },
UpdateExpression: "SET followers = followers + :i",
ExpressionAttributeNames: {"followers": "followers"},
// UpdateExpression: "ADD followers :i",
// ExpressionAttributeNames={'followers': 'followers'},
// ExpressionAttributeValues: {":i": {"N": "1"}},
// UpdateExpression: "set followers = followers + :i",
ExpressionAttributeValues:{ ":i": {N: 1}},
ReturnValuesOnConditionCheckFailure: "ALL_OLD"
}
},
// {
// Update:{
// TableName: "rememoriesDBv2",
// Key: { "PK": followingUser, "SK":followingMetadata},
// UpdateExpression: "SET following = following + :i",
// // UpdateExpression: "set following = following + :i",
// ExpressionAttributeValues: {":i": 1},
// ReturnValuesOnConditionCheckFailure: "ALL_OLD"
// }
// },
]}).promise();
}
catch(err){
console.log(err)
}
// TODO implement
const returnValue = {
statusCode: 200,
body: JSON.stringify(event.queryStringParameters.followingUser + " is now following " + event.queryStringParameters.followedUser),
};
return returnValue;
};
I've been running into problems the entire time, but here is the current error:
INFO ValidationException: ExpressionAttributeNames contains invalid key: Syntax error; key: "followers"
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:51:27)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
code: 'ValidationException',
time: 2020-07-31T15:34:22.073Z,
requestId: 'B6NJ2EC686PFVBFE0P4MVFBB17VV4KQNSO5AEMVJF66Q9ASUAAJG',
statusCode: 400,
retryable: false,
retryDelay: 47.858884374085854
}
I've also gotten this error:
INFO ValidationException: Invalid UpdateExpression: Incorrect operand type for operator or function; operator or function: +, operand type: M
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:51:27)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
code: 'ValidationException',
time: 2020-07-31T14:19:56.774Z,
requestId: 'ROQC1RTQTD4784CK8JBQ47FKKBVV4KQNSO5AEMVJF66Q9ASUAAJG',
statusCode: 400,
retryable: false,
retryDelay: 31.52114733740706
}
Ultimately, I'm unable to find much AWS documentation, and am not sure where to go from here. If anyone could help me find out what exactly is going on with my code and what is wrong with it, it'd be greatly appreciated.
Here is the table schema
It then has random elements depending on the type.

Related

Nodemailer: Missing start boundary with ses transporte

import * as SES from 'aws-sdk/clients/ses';
import * as nodemailer from 'nodemailer';
const transporter = nodemailer.createTransport({SES: new SES({
accessKeyId: 'XXXX',
secretAccessKey: 'XXXX',
region: 'XXXX',
})});
transporter.sendMail({
from: 'test-from#test.it',
to: 'test-to#test.it',
attachments: [{
filename: 'attachment.zip',
content: file // internal.Readable from busboy upload
}],
subject: 'test',
html: 'test'
});
error:
InvalidParameterValue: Missing start boundary
at Request.extractError (/opt/backend/node_modules/aws-sdk/lib/protocol/query.js:50:29)
at Request.callListeners (/opt/backend/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/opt/backend/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/opt/backend/node_modules/aws-sdk/lib/request.js:686:14)
at Request.transition (/opt/backend/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/opt/backend/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /opt/backend/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/opt/backend/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/opt/backend/node_modules/aws-sdk/lib/request.js:688:12)
at Request.callListeners (/opt/backend/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
libs
{
"nodemailer": "^6.7.6",
"aws-sdk": "^2.1167.0"
}

AWS Lambda Error: Validation Exception Value [] at 'names' failed to satisfy constraint: Member must have a length greater than or equal to 1

I have a lambda function which is triggered by an AWS SNS Topic. The function takes the information passed in from the SNS event and send's an email to a user using Nodemailer.
When I run my lambda function locally it works correctly. But once it's deployed I get the following error in my CloudWatch logs:
ValidationException: 1 validation error detected: Value '[]' at 'names' failed to satisfy constraint: Member must have length greater than or equal to 1.
at Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/json.js:52:27)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:688:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:690:12)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
code: 'ValidationException',
time: 2021-10-01T18:02:30.538Z,
requestId: '023d6346-a49a-4dc6-a07f-92bd578a3601',
statusCode: 400,
retryable: false,
retryDelay: 94.04142545650443
}
This is the code for my lambda function:
const pug = require('pug');
const {newTransporter} = require('./handlers/emailTransporter');
exports.handler = async (event, context) => {
const message = event.Records[0].Sns.Message;
const mailAddressObj = {
'userEmail' : message.mail.commonHeaders.replyTo,
'clientEmail' : message.mail.commonHeaders.to[0],
}
const {userEmail, clientEmail} = mailAddressObj;
const html = pug.compileFile('./views/bounceNotificationEmail.pug');
const mailOptions = {
from: 'sendingEmail#email.com',
to: 'clientEmail,
subject: `Subject Header`,
html: html({
client_email: clientEmail
}),
};
try {
let transporter = await newTransporter();
let info = await transporter.sendMail(mailOptions);
console.log("Message sent: %s", info.messageId);
return info;
}
catch (e) {
console.log(e, 'error')
}
return console.log(mailAddressObj);
};
for starters in your example you don't close the quote after the "to" parameter :P
on a more serious note however, I reckon that when you run this locally, you wrote an JSON event that triggers your lambda manually and it doesn't have the same shape as the real life event produced by SNS. In your specific case, message that you initialize in the first line of your function is in fact a string, yet you use it as an object.
What you should have done is
const message = JSON.parse(event.Records[0].Sns.Message);

dynamodb TransactWriteItems error: An unknown operation was requested

I'm trying to update multiple items using TransactWriteItems, But I have got the following error:
{
UnknownOperationException: An unknown operation was requested.
at Request.extractError (project-dir\node_modules\aws-sdk\lib\protocol\json.js:51:27)
at Request.callListeners (project-dir\node_modules\aws-sdk\lib\sequential_executor.js:106:20)
at Request.emit (project-dir\node_modules\aws-sdk\lib\sequential_executor.js:78:10)
at Request.emit (project-dir\node_modules\aws-sdk\lib\request.js:683:14)
at Request.transition (project-dir\node_modules\aws-sdk\lib\request.js:22:10)
at AcceptorStateMachine.runTo (project-dir\node_modules\aws-sdk\lib\state_machine.js:14:12)
at project-dir\node_modules\aws-sdk\lib\state_machine.js:26:10
at Request.<anonymous> (project-dir\node_modules\aws-sdk\lib\request.js:38:9)
at Request.<anonymous> (project-dir\node_modules\aws-sdk\lib\request.js:685:12)
at Request.callListeners (project-dir\node_modules\aws-sdk\lib\sequential_executor.js:116:18)
message: 'An unknown operation was requested.',
code: 'UnknownOperationException',
time: 2019-06-21T18:28:46.776Z,
requestId: '',
statusCode: 400,
retryable: false,
retryDelay: 17.98291928629798
}
My Code is given below:
const dynamodb = new aws.DynamoDB({ endpoint: "http://localhost:8000" });
const result = await dynamodb
.transactWriteItems({
TransactItems: [{
"Update":{
"TableName":"dbTable1",
"Key":{
"id": { "S":"table-primary-key-id-01" }
},
"ConditionExpression": "#id = :id",
"UpdateExpression":"set #orderNo = :orderNo",
"ExpressionAttributeNames": {
"#id": "id",
"#orderNo":"orderNo"
},
"ExpressionAttributeValues":{
":id":{"S":"table-primary-key-id-01"},
":orderNo":{"N":"9"}
}
}
}]
})
.promise();
Any help would be very much appreciable. Thanks in advance.
I see you are running the TransactWriteItems operation on a local dynamodb instance. Unfortunately AWS has not implemented support for Transactions API call for dynamodb local instances.

TypeError: Cannot read property 'state' of undefined when calling for state

I'm trying to use Alexa to search dynamoDB for the corresponding state at certain dates and times.
Im currently getting the following error in cloud watch
TypeError: Cannot read property 'state' of undefined
Here is the full error
2018-05-18T09:25:50.175Z 73ac1779-5a7d-11e8-85af-e35ca28db9ce TypeError: Cannot read property 'state' of undefined
at Response.<anonymous> (/var/task/index.js:40:28)
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:364:18)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:685:12)
Im also getting the following
2018-05-18T09:25:50.174Z 73ac1779-5a7d-11e8-85af-e35ca28db9ce loaded data item:
undefined
Can anyone help me figure this out?
Here is the lines that the error refers to.
dbClient.query(params, function (err, data) {
if (err) {
// failed to read from table for some reason..
console.log('failed to load data item:\n' + JSON.stringify(err, null, 2));
// let skill tell the user that it couldn't find the data
sendResponse(context, callback, {
output: "the data could not be loaded from your database",
endSession: false
});
} else {
let dataItem = data.Items[0];
console.log('loaded data item:\n' + JSON.stringify(dataItem, null, 2));
// assuming the item has an attribute called "state"..
sendResponse(context, callback, {
output: dataItem.state,
endSession: false
});
}
});
};
function sendResponse(context, callback, responseOptions) {
if(typeof callback === 'undefined') {
context.succeed(buildResponse(responseOptions));
} else {
callback(null, buildResponse(responseOptions));
}
}
function buildResponse(options) {
var alexaResponse = {
version: "1.0",
response: {
outputSpeech: {
"type": "SSML",
"ssml": `<speak><prosody rate="slow">${options.output}</prosody></speak>`
},
shouldEndSession: options.endSession
}
};
if (options.repromptText) {
alexaResponse.response.reprompt = {
outputSpeech: {
"type": "SSML",
"ssml": `<speak><prosody rate="slow">${options.reprompt}</prosody></speak>`
}
};
}
return alexaResponse;
}
UPDATE
I have also found this error in cloud watch
2018-05-18T14:46:37.928Z 3158fac8-ea71-4305-a2be-dda782b58531 Unexpected error occurred in the skill handler! TypeError: Cannot read property 'type' of undefined
at exports.handler (/var/task/index.js:81:17)
and as requested here is the error with load item
2018-05-18T14:46:45.592Z 48df3d5d-5aaa-11e8-aa8c-f3f6ecf5748a loaded data item:
undefined

AWS Rekognition Error - InvalidparameterException

const AWS = require('aws-sdk');
AWS.config.loadFromPath('./config.json');
const rekognition = new AWS.Rekognition({apiVersion: '2016-06-27'});
const constants = require('./constants');
const s3BucketName = constants.s3BucketName;
const s3BucketKeyName = constants.s3FacebookBucketKey;
const params = {
Image: {
S3Object: {
Bucket: "mastekinnoations3learning",
Name: "1527119837382460.jpeg"
}
}
};
rekognition.detectFaces(params, function(err, data) {
if (err)
console.log(err, err.stack); // an error occurred
else {
console.log(data); // successful response
}
});
I am trying to execute the above code which was running successfully last month but it has stopped running suddenly giving error "InvalidParameterException". Any help no what I am missing will be of great help!!
The image that I am using is this
https://s3-us-west-2.amazonaws.com/mastekinnoations3learning/1527119837382460.jpeg
Detailed Error:
{ InvalidParameterException: Request has Invalid Parameters
at Request.extractError (D:\Saurabh jain\Personal\nodejsprojects\ImageUpload\node_modules\aws-sdk\lib\protocol\json.js:48:27)
at Request.callListeners (D:\Saurabh jain\Personal\nodejsprojects\ImageUpload\node_modules\aws-sdk\lib\sequential_executor.js:106:20)
at Request.emit (D:\Saurabh jain\Personal\nodejsprojects\ImageUpload\node_modules\aws-sdk\lib\sequential_executor.js:77:10)
at Request.emit (D:\Saurabh jain\Personal\nodejsprojects\ImageUpload\node_modules\aws-sdk\lib\request.js:683:14)
at Request.transition (D:\Saurabh jain\Personal\nodejsprojects\ImageUpload\node_modules\aws-sdk\lib\request.js:22:10)
at AcceptorStateMachine.runTo (D:\Saurabh jain\Personal\nodejsprojects\ImageUpload\node_modules\aws-sdk\lib\state_machine.js:14:12)
at D:\Saurabh jain\Personal\nodejsprojects\ImageUpload\node_modules\aws-sdk\lib\state_machine.js:26:10
at Request.<anonymous> (D:\Saurabh jain\Personal\nodejsprojects\ImageUpload\node_modules\aws-sdk\lib\request.js:38:9)
at Request.<anonymous> (D:\Saurabh jain\Personal\nodejsprojects\ImageUpload\node_modules\aws-sdk\lib\request.js:685:12)
at Request.callListeners (D:\Saurabh jain\Personal\nodejsprojects\ImageUpload\node_modules\aws-sdk\lib\sequential_executor.js:116:18)
The issue was with the image. It seems its corrupt(still it opens perfectly in MSPaint). If I open the image in MSPaint and save it as JPEG and they try to pass it to AWS Rekognition , it works correctly. Hence I tried a different approach to download the image from facebook page and the application worked.
Thanks!!
In the config.json, there is something.
Try this out
AWS.config.update({region:'us-east-1',accessKeyId:'',secretAccessKey:''});
Let's change Bucket this.
const s3bucket = new AWS.S3({params: {Bucket: ''}}); //name Bucket you
Try this code. Required Attributes
const params = {
Image: {
S3Object: {
Bucket: "mastekinnoations3learning",
Name: "1527119837382460.jpeg"
}
},
Attributes:["ALL"]
};
Ref: AWS SDK for JavaScript - Class: AWS.Rekognition

Resources