1

On Cloudwatch I'm having an error that says:

HTTP/1.1" 500 35 ZHTFXgWBoAYEQ4a= The Lambda function returned the following error: "Unhandled". Check your Lambda function code and try again.

I'm trying to build the new HTTP API Gateway with a simple lambda function.

This is my lambda function:

const AWS = require("aws-sdk");
const dynamodb = new AWS.DynamoDB({
  region: "us-east-1",
  apiVersion: "2012-08-10"
});

exports.handler = (event, context, callback) => {
  const params = {
    Key: {
      id: {
        S: event.id
      }
    },
    TableName: "todos"
  };
  dynamodb.getItem(params, (err, data) => {
    if (err) {
      console.log(err);
      callback(err);
    } else {
      callback(null, {
        id: data.Item.id.S,
        title: data.Item.title.S,
        watchHref: data.Item.watchHref.S,
        authorId: data.Item.authorId.S,
        length: data.Item.length.S,
        category: data.Item.category.S
      });
    }
  });
};

This is how the data is structured: enter image description here

This is how I'm invoking it and the JSON response I get:

enter image description here

What am I doing wrong?

EDIT: Here's a more detailed log:

"ValidationException: Supplied AttributeValue is empty, must contain exactly one of the supported datatypes",

But I'm giving it the right values, or not?

ElKePoN
  • 822
  • 11
  • 21
  • If you look at the lambda logs (there should be a link to the cloudwatch logs for your lambda on the function view in the AWS GUI), there should be more helpful information there. – Zac Anger Jan 13 '21 at 03:46
  • @ZacAnger thanks, I went there and pasted the new log. It's like it's not finding the values? It says empty – ElKePoN Jan 13 '21 at 03:57

2 Answers2

2

Lambda response should be of specific format for API Gateway to recognize and respond correctly

  • Actual Api Response should be converted to String and passed to body.

  • Entire JSON with statusCode, body, headers, isBase64Encoded should be pass as response from Lambda.

  • For success callback(null, responseObject)

  • For Failures callback(responseObject)
    here is an example of responseObject:

     {
      "statusCode": 200,
      "body": "{\"id\":\"1\",\"title\":\"My Title\"}",
      "isBase64Encoded": false,
      "headers": {
          "Content-Type": "application/json"
      }
    }
    
Balu Vyamajala
  • 9,287
  • 1
  • 20
  • 42
2

The detailed error log you found points to a validation error. This means that in your request to Dynamo, the object you're using (params) is invalid. The shape looks correct according to the docs, so it must mean that your event.id is an empty string or null when it hits your function. You're sending the ID from Postman as a query parameter, are you mapping it somewhere else? If not you'll want to use event.queryStringParameters.id and the proxy integration as explained here.

Zac Anger
  • 6,983
  • 2
  • 15
  • 42
  • thanks for the hint, I put a logger on the event.id and it's `undefined`, why it's not getting the id from the DB – ElKePoN Jan 13 '21 at 04:27
  • I changed the line for id to `event.queryStringParameters.id` and it worked! Can you explain more what's going on please? – ElKePoN Jan 13 '21 at 04:29
  • 1
    `event` is whatever information comes from the invoker (API Gateway in this case). The Lambda proxy integration sends on the whole request that originally hit API Gateway, which is why it needs to be enabled to get the query parameters. The docs on that are [here](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html). IMHO it should be the default setting :) – Zac Anger Jan 13 '21 at 04:39
  • I still have the question of what you said about activating the proxy integration, I thought I did activated it. So if I have to use `event.queryStringParameters.id` instead of `event` that means I don't have it activated? – ElKePoN Jan 14 '21 at 00:52
  • 1
    No, that means you do. If you didn't have it activated, `event.queryStringParameters` would be undefined. Either way `id` wouldn't have been on the `event` object because it wasn't part of the request body and you aren't the one [invoking](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestBody) the lambda, API Gateway is. – Zac Anger Jan 14 '21 at 00:58