Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DynamoDB batchWriteItem crashes in node.js

I'm trying to use batchWriteItem in the aws-sdk and am running into an error that crashes node. The weird part is that my items DO get written to the DB. The error happens inside the sdk.

My code is:

function sendItems(params) {
    console.log("SENDING:");
    console.log(params);
    dynamodb.batchWriteItem(params, function(err, data) {
        console.log("Response from DynamoDB");
        if(err) console.log(err);
        else    console.lod(data);
    }); 
}

var toSave = [];
for(name in names) {
    var item = {
      Id:         { S: uuid.v4() },
      Name:       { S: name }
    };
    toSave.push(item);
}

var items = [];
for(var i = 0; i < toSave.length; i++) {
    items[i] = {
        PutRequest: { Item: toSave[i] }
    }
}

var params = {
    RequestItems: {
        'MyTableName': items
    },
    ReturnConsumedCapacity: 'TOTAL',
    ReturnItemCollectionMetrics: 'SIZE'
};

sendItems(params);

The stack trace of the error is:

/Users/gsimons/node_modules/aws-sdk/lib/request.js:30
        throw err;
              ^
TypeError: undefined is not a function
at Response.<anonymous> (/Users/gsimons/Documents/workspace/testing/aws-put-items.js:62:21)
    at Request.<anonymous> (/Users/gsimons/node_modules/aws-sdk/lib/request.js:353:18)
    at Request.callListeners (/Users/gsimons/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
    at Request.emit (/Users/gsimons/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
    at Request.emit (/Users/gsimons/node_modules/aws-sdk/lib/request.js:595:14)
    at Request.transition (/Users/gsimons/node_modules/aws-sdk/lib/request.js:21:10)
    at AcceptorStateMachine.runTo (/Users/gsimons/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /Users/gsimons/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/Users/gsimons/node_modules/aws-sdk/lib/request.js:37:9)
    at Request.<anonymous> (/Users/gsimons/node_modules/aws-sdk/lib/request.js:597:12)

Now what really gets me is when I look at node_modules/aws-sdk/lib/request.js:

21:    self.emit(self._asm.currentState, function(err) {
22:      if (err) {
23:        if (isTerminalState(self)) {
24:          if (domain && self.domain instanceof domain.Domain) {
25:            err.domainEmitter = self;
26:            err.domain = self.domain;
27:            err.domainThrown = false;
28:            self.domain.emit('error', err);
29:          } else {
30:            throw err;
31:          }
32:        } else {
33:          self.response.error = err;
34:          done(err);
35:        }
36:      } else {
37:        done(self.response.error);
38:      }
39:    });

It seems very odd that there is effectively the following happening:

if(err) {
  //err must be defined here, right?
  //No code modifies err or sets it to undefined.
  //Is it possible that another thread altered err
  //  between the call to the function and the call to throw?
  throw err; //Should just throw err back up.
}

Could this be a bug in the aws js sdk?

like image 435
Geoff Simons Avatar asked Nov 09 '22 07:11

Geoff Simons


1 Answers

Replace :

for(name in names) {
    var item = {
      Id:         { S: uuid.v4() },
      Name:       { S: name }
    };
    toSave.push(item);
}

with :

var toSave = [];
names.forEach(function(name){
    var item = {
      Id:         { S: uuid.v4() },
      Name:       { S: name }
    };
    toSave.push(item);
});

I was facing the same problem but the above solution fixed it for me. That is assuming that the names variable in your code is an array.

like image 172
jaywalker Avatar answered Nov 14 '22 21:11

jaywalker