4

I'm getting this error from lambda: errorType":"Runtime.UnhandledPromiseRejection","errorMessage":"Error: Unable to stringify response body

I'm trying to trigger my lambda from an upload in s3 (this part is working) and then that should post something into dynamoDB

here is my lambda in full

var AWS = require('aws-sdk');
var S3 = require('aws-sdk/clients/s3');

const s3 = new AWS.S3()
var DynamoDB = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event) => {
    // TODO implement
    var bucket = event['Records'][0]['s3']['bucket']['name']
    var json_file_name = event['Records'][0]['s3']['object']['key']
    var params = {
      Bucket: bucket, 
      Key: json_file_name
     };

    const data = await s3.getObject(params).promise();

    const dataToDb = data.Body.toString('utf-8');

    console.log(dataToDb, 'TESTING ====')

    var dbparams = {
        TableName: "MY-TABLE-NAME",
        Item: dataToDb, 
    };

    const putIntoDB = await DynamoDB.put(dbparams, function (err) {
         if (err) {
             console.log(err, 'er===');
         }
        else {
            console.log(dbparams, 'db====')
        }
    });

    return putIntoDB
};

the data that is coming from s3 is just a simple json object with 4 keys so nothing big at all. my table consists of just a primary key called user_id and that field IS in my json object that comes back from S3 so no idea why this isn't working?

1
  • 2
    "Lambda error: Unable to stringify response body" would be a much much better and search engine friendly title. Commented Dec 24, 2020 at 2:43

2 Answers 2

8

DynamoDB.put is a callback and you are trying to await on it, so this will never work. You should chain the .promise() method just like you did with your s3.getObject call.

await DynamoDB.put(dbparams).promise()

If you want to handle errors, just wrap it in a try/catch block:

try {
    await DynamoDB.put(dbparams).promise()
} catch (e) {
    console.log(e)
}

On top of that, you also need to feed the Item attribute of your DynamoDB call with a JSON object, not with a string.

I am not sure what you get from s3, but converting it to a JSON object by using JSON.parse(dataToDb) should do the trick given the data is a valid JSON object.

Sign up to request clarification or add additional context in comments.

6 Comments

ok when I try that I'm getting this: ` { TableName: 'richjmatt-test-ddb', Item: '{\n "name": "Rich",\n "age": 26,\n "city": "London",\n "user_id": "1"\n}\n' } ` how can I remove these newlines? it's saying I'm missing the key "user_id" but clearly it is there...
because item is a String and not a JSON object. You converted it to a String yourself. I am not sure what you get back from s3, but if the content itself is not a JSON, just run JSON.parse(dataToDb) and that should work
what. the. flip. I swear i tried that. anyway it worked! thanks man
No problem. I also edited my answer to reflect the JSON part which I completely overlooked in my initial answer.
@bubble-cord that's because without the .promise() call, you are invoking the SDK's callback functions instead of promises, which means that awaiting on callbacks wouldn't have any effect
|
0

UTF-8 encoding is usually utf8 when used as an argument in node. I would start there.

1 Comment

'utf8' and 'utf-8'are both valid and equivalent here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.