4

I have following code:

var AWSXRay = require('aws-xray-sdk');
    var AWS = AWSXRay.captureAWS(require('aws-sdk'));
    const client = AWSXRay.captureAWSClient(new AWS.DynamoDB.DocumentClient({region : 'eu-west-1'}));
    exports.handler = function(event, context, callback) {

        AWSXRay.captureFunc('annotations', function(subsegment){
        subsegment.addAnnotation('User', **);
        subsegment.addAnnotation('Name', **);
      });

         var params = {
            TableName: "****",
            ** all params **
            };
     client.query(params, function(err, data) {
       if (err) console.log(err, err.stack); // an error occurred
       else{
            callback(null,data);
            }
        });
    }

When executing the code above, the following error is thrown:

Response:
{
  "errorMessage": "service.customizeRequests is not a function",
  "errorType": "TypeError",
  "stackTrace": [
    "Object.<anonymous> (/var/task/index.js:5:24)",
    "Module._compile (module.js:570:32)",
    "Object.Module._extensions..js (module.js:579:10)",
    "Module.load (module.js:487:32)",
    "tryModuleLoad (module.js:446:12)",
    "Function.Module._load (module.js:438:3)",
    "Module.require (module.js:497:17)",
    "require (internal/module.js:20:19)"
  ]
}

following are the logs of function:

Function Logs:
START RequestId: Version: $LATEST
module initialization error: TypeError
    at Object.captureAWSClient (/var/task/node_modules/aws-xray-sdk-core/lib/patchers/aws_p.js:55:11)
    at Object.<anonymous> (/var/task/index.js:5:24)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
END

How should I resolve this?

Zoe
  • 27,060
  • 21
  • 118
  • 148
ABCD
  • 730
  • 1
  • 13
  • 31
  • 1
    This could be an issue caused by how DynamoDB document client instantiate the real low level client. Do you see the same error if you change the client to some other service like S3 or EC2? If not there is a workaround that could potentially work for you but please let me know if it doesn't: https://forums.aws.amazon.com/thread.jspa?messageID=821510󈤆 – haotian465 Oct 31 '18 at 20:30
  • yes, thanks that worked for me.... Thank you....@haotian465 – ABCD Nov 01 '18 at 06:34

3 Answers3

3

Posting the short-term workaround here for better visibility.

const ddbClient = AWSXray.captureAWSClient(new AWS.DynamoDB({...}));
const client = new AWS.DynamoDB.DocumentClient({
  service: ddbClient
});
client.service = ddbClient;

See some reasoning and discussion here https://forums.aws.amazon.com/thread.jspa?messageID=821510&#821510

Zoe
  • 27,060
  • 21
  • 118
  • 148
haotian465
  • 679
  • 3
  • 4
  • This solution doesn't work as of October 2021. Getting TypeError: service.customizeRequests is not a function – Anton N Oct 12 '21 at 10:42
1

The solutions here didn't work for me. While they removed the error, I didn't then see any DynamoDB calls logged within AWS X-Ray either.

Rather than try to update the DocumentClient to set an instrumented service, I tried capturing everything, and that worked for me.

import * as uninstrumentedAWS from 'aws-sdk'
import * as AWSXRay from 'aws-xray-sdk'
const AWS = AWSXRay.captureAWS(uninstrumentedAWS);

const client = new AWS.DynamoDB.DocumentClient();
await client.put({ TableName: "helloTable", Item: { "_id": (new Date()).toISOString() }}).promise();
a-h
  • 4,244
  • 2
  • 23
  • 29
0

client doesn't have .service public variable. That said, this one is working for me:

import * as AWS  from 'aws-sdk'
import * as AWSXRay from 'aws-xray-sdk'
import { DocumentClient } from 'aws-sdk/clients/dynamodb'

export class DynDBAccess {
    private readonly docClient: DocumentClient // = new AWS.DynamoDB.DocumentClient(),

    constructor(
        private enableAWSX:boolean,      
    ){
        if(this.enableAWSX)
        {
           logger.info('AWSX: enable')
           const ddbClient = AWSXRay.captureAWSClient(new AWS.DynamoDB({
            ////Uncomment below to use serverless-dynamodb-local
            //region: 'localhost',
            //endpoint: 'http://localhost:8001',
            //accessKeyId: 'DEFAULT_ACCESS_KEY',  // needed if you don't have aws credentials at all in env
            //secretAccessKey: 'DEFAULT_SECRET',
           }));
           this.docClient = new AWS.DynamoDB.DocumentClient({
            service: ddbClient
          });

        }
...

martin
  • 862
  • 9
  • 28
  • The workaround mentioned in the answer still works. As per the [document_client](https://github.com/aws/aws-sdk-js/blob/3616156b0ca66f652f0ef8bec41369ebac886994/lib/dynamodb/document_client.js#L69) code, the service variable can be configured. This approach works as well :) – Prashant Srivastava Jun 01 '20 at 15:00