0

Objective: show errors on AWS X-ray (all errors from lambda).

'use strict';

const AWSXRay = require('aws-xray-sdk-core'),
     AWS = AWSXRay.captureAWS(require('aws-sdk')),
    env = process.env;

AWS.config.update({
    region: env.REGION
});


const dynamodbDocumentClient = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event, context, callback) => {
    let seg=AWSXRay.getSegment();
    try {
        const params = {
            /*PARAMS HERE*/
          };
          let res = await dynamodbDocumentClient.scan(params).promise();
        throw('ERROR FOR TESTING');
        return res;
        //callback(null,res);

    }
    catch(err) {
        let subseg=seg.addNewSubsegment('error');
        subseg.addMetadata("error", "error", "my_error");
        subseg.addAnnotation('errr', 'this is a test');
        subseg.addError(err);
        subseg.addErrorFlag();
        subseg.close();
        console.log('==ERROR==',err);
        return err;
    }
};

When I use AWSXRay.captureAWS the subsegment 'error' doesnt show on X-ray. If I dont use captureAWS the error appear in X-ray correctly.

Alvaro
  • 11
  • 3

1 Answers1

0

The issue is likely with how you're structuring your Lambda. First, you shouldn't be using callback in an async function handler, async function handlers should return native promises or errors per the docs.

If you want to use a callback to return the result of your function, which it seems like you do, the handler should be synchronous. That being said, you're throwing your error after the callback, which will not be reflected in X-Ray because the X-Ray segment for Lambda functions closes when the callback is called. If an error is thrown before the callback (e.g. during the DynamoDB call) it should be captured in your error subsegment.

EDIT

After the original post was edited, I was unable to reproduce the error with this code:

const AWSXRay = require('aws-xray-sdk');
const AWS = AWSXRay.captureAWS(require('aws-sdk'));

const ddb = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event, context) => {
    try { 
        const res = await ddb.scan({TableName: 'scorekeep-game'}).promise();
        throw('Test Error');
        return result;
    } catch (e) {
        console.log('caught!');
        var sub2 = AWSXRay.getSegment().addNewSubsegment('err');
        sub2.addError(e);
        sub2.addErrorFlag();
        sub2.close();
        return e;
    }
};
William Armiros
  • 267
  • 1
  • 10
  • Sorry, I didnt notice that I put the wrong throw in this post thanks. I have corrected the post. – Alvaro Jan 09 '20 at 19:19
  • I was not able to reproduce the issue described in my own Lambda environment; the error subsegment appeared in my X-Ray console with the attached error and other metadata both with and without an instrumented AWS client. Can you provide the raw data of your trace from the X-Ray console? – William Armiros Jan 09 '20 at 20:05
  • using captureAWS?. (capturing aws services and custom errors too) Here is the trace: http://notes.io/81ve – Alvaro Jan 09 '20 at 22:59
  • Yes. Edited my post. – William Armiros Jan 10 '20 at 00:09
  • I just copy/paste your code. (changing the tableName). and It only shows me the dynamo stream not the subsegment err. I have enabled x-ray for the lambda. – Alvaro Jan 13 '20 at 15:57
  • Huh - super interestingly it seems to work (the error subsegment appears) in Node 12 and not in Node 10. Based on the Node ChangeLog I have no idea what would cause this. Feel free to look around for a solution and post it here. – William Armiros Jan 13 '20 at 21:59
  • Thats right it works in Node 12 and not in Node 10, thanks. I will look around for a solution for Node 10 and post it here. – Alvaro Jan 13 '20 at 22:35