11

Created a Lambda function to get analysis from AWS Textract API. Here is the relevant code (Node.js 12)

exports.handler = async (event, context, callback) => {
 ...    
 
   let request = textract.getDocumentAnalysis(params);
   request.send((err, data) => {
       if (err) console.log(err, err.stack);
       else console.log(data);
   });
   
    callback(null, request);
}; 

In CloudWatch logs get this error:

ERROR   Invoke Error    
{
    "errorType": "Error",
    "errorMessage": "Unable to stringify response body",
    "stack": [
        "Error: Unable to stringify response body",
        "    at _trySerializeResponse (/var/runtime/RAPIDClient.js:175:11)",
        "    at RAPIDClient.postInvocationResponse (/var/runtime/RAPIDClient.js:45:22)",
        "    at complete (/var/runtime/CallbackContext.js:33:12)",
        "    at callback (/var/runtime/CallbackContext.js:43:7)",
        "    at /var/runtime/CallbackContext.js:104:16",
        "    at Runtime.exports.handler (/var/task/index.js:92:5)",
        "    at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
    ]
}

When I modify the callback: callback(null, request.X) ... lambda returns the data object from Textract. I at first thought that I had to drill down into the data object (request.DocumentMetadata) ... but works with any string of characters I put in front of "request." (at least the ones I've tried). Any help with this is appreciated.

1 Answer 1

9

I was using the above approach due to following AWS SDK API documentation closely. However, I found another approach, which solved all issues (which were many). Maybe someone can explain why.

Here is solution.

let results = await textract.getDocumentAnalysis(params, (err, data) => {
    if(err) console.log(err, err.stack);
    else console.log(data);
}).promise();

callback(null, results);

The answer is relates to the aws-skd (for js). Here is the url: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html#promise-property[][1]

For any async request (think all or most all AWS api request will be async), you need a Promise...then. With AWS request you need a "thenable" promise ... so to the end of the request you add: promise()

Straight from AWS docs which can be a bit cryptic I think:

var request = s3.putObject({Bucket: 'bucket', Key: 'key'});
var result = request.promise();
result.then(function(data) { ... }, function(error) { ... });

If I were to write the above like this:

async function(){
  const params = {Bucket: 'bucket', Key: 'key'};
  await s3.putObject(params, (err, data) => {
    if (err) function(err){ ... }; 
    else function(data) { ... };
  }).promise();
};
Sign up to request clarification or add additional context in comments.

2 Comments

the calls to a function on the AWS SDK for example I was working with the AWS.Rekognition always expect a promise.
@Mark. Even I am facing the same issue. I am fetching data from the Aurora DB something like this: const data = await rdsDataService.executeStatement(params, (err, res) => { if (err) console.log(err.stack); else console.log(res)}).promise(); callback(null, data). But it starts giving error 4fdb13 Task timed out after 6.01 seconds". If I remove the promise(), then also it doesn't make any difference. Timeout error still perists. Can you help please ?

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.