How can I fix the 'TypeError: Cannot read property 'origin' of undefined' error in AWS Lambda function?

huangapple go评论52阅读模式
英文:

How can I fix the 'TypeError: Cannot read property 'origin' of undefined' error in AWS Lambda function?

问题

以下是您要翻译的内容:

"errorType": "TypeError",
"errorMessage": "Cannot read property 'origin' of undefined",
"trace": [
"TypeError: Cannot read property 'origin' of undefined",
" at responseHeaders (/var/task/index.js:32:26)",
" at /var/task/index.js:124:22",
" at processTicksAndRejections (internal/process/task_queues.js:95:5)"
]

What could be causing this error?

/**********************************************************************
 *  Upsert Answer item into table
 **********************************************************************/

/* POST test
  {
    "resource": "/",
    "path": "/",
    "httpMethod": "POST",
    "body": "{\"answer\":\"This is my super important answer\",\"questionSlug\":\"this-is-my-super-important-answer\"}"
  }

  PUT test - make sure to change the ID to one in your database before running or this method will create a new record
  {
    "resource": "/",
    "path": "/",
    "httpMethod": "PUT",
    "body": "{\"answer\":\"This is my super important answer\",\"negativeVotes\":0,\"positiveVotes\":1,\"id\":\"5ec9957e3f64b70004e7599e\"}"
  }
*/

// we need access to the AWS SDK
var AWS = require("aws-sdk");

// we need uuid to generate unique ids
const { v4: uuidv4 } = require("uuid");

//  we need access to DynamoDB and choose the DocumentClient model
var docClient = new AWS.DynamoDB.DocumentClient();

const responseHeaders = (headers) => {
  const origin = headers.origin || headers.Origin;

  return {
    // HTTP headers to pass back to the client
    "Content-Type": "application/json",
    // the next headers support CORS
    "X-Requested-With": "*",
    "Access-Control-Allow-Headers":
      "Content-Type,X-Amz-Date,Authorization,X-Api-Key,x-requested-with",
    "Access-Control-Allow-Origin": origin,
    "Access-Control-Allow-Methods": "OPTIONS,*",
    Vary: "Origin", // for proxies
    // the "has-cors" library used by the Angular application wants this set
    "Access-Control-Allow-Credentials": "true",
  };
};

exports.handler = async (event) => {
  // get the HTTP Method used
  var httpMethod = event.httpMethod;
  // get the HTTP body sent
  var payload = JSON.parse(event.body);

  // time to prepare the upsert
  const paramQuery = async () => {
    // define our query
    let params = {
      TableName: "Answer",
      Key: { id: "" },
      UpdateExpression: "set #qi = :qi, #a = :a, #nv = :nv, #pv = :pv",
      ExpressionAttributeNames: {
        // define the attributes used in the update expression
        "#qi": "questionId",
        "#a": "answer",
        "#nv": "negativeVotes",
        "#pv": "positiveVotes",
      },
      ExpressionAttributeValues: {
        // set default values
        ":qi": "",
        ":a": "",
        ":nv": 0,
        ":pv": 0,
      },
      // this tells DynamoDB to return the new records with all fields, not just the changed ones
      // see https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html for
      // information on the possible values
      ReturnValues: "ALL_NEW",
    };

    // these three fields can be set during create or update
    //  set the answer if there is one
    if (payload.answer && payload.answer.trim())
      params.ExpressionAttributeValues[":a"] = payload.answer;

    //  set the category slug if there is one
    if (payload.questionId && payload.questionId.trim())
      params.ExpressionAttributeValues[":qi"] = payload.questionId;

    if (httpMethod == "PUT") {
      // PUTs are updates but the ID is passed as a path paremeter
      // lets get the path parameters
      let pathParameters = event.pathParameters;

      //  set the unique key of the item to be modified
      params.Key.id = pathParameters.id;

      // these two values are only changed - they are always defaulted during create
      //  set the negativeVotes
      params.ExpressionAttributeValues[":nv"] = payload.negativeVotes;

      //  set the positiveVotes
      params.ExpressionAttributeValues[":pv"] = payload.positiveVotes;
    } else {
      // POSTs are inserts
      // create and set the unique key. its a uuid without the '-'
      var id = uuidv4().replace(/-/g, "");
      params.Key.id = id;
    }

    // uncomment the next line to see the parameters as sent to DynamoDB
    //console.log(JSON.stringify(params));

    // we create a promise to wrap the async DynamoDB execution
    return new Promise((resolve, reject) => {
      var queryParams = docClient.update(params).promise();
      queryParams
        .then(function (data) {
          resolve({
            statusCode: 200,
            body: JSON.stringify(data),
            // HTTP headers to pass back to the client
            headers: responseHeaders(event.headers),
          });
        })
        .catch(function (err) {
          reject(err);
        });
    });
  };
  // we await our promise here and return the result (see the resolve above)
  return await paramQuery();
};

I tried adding quotes around origin in the properties section, and was expecting data returned. But I still got the same error.

英文:

I trying to test an lambda function in AWS where an answer is inserted in a table. I have attached the security policy. I have made sure that the questionID in the UpsertAnswer lambda matches the questionID of the UpsertQuestion lambda. But I keep getting an error that says:

"errorType": "TypeError",
"errorMessage": "Cannot read property 'origin' of undefined",
"trace": [
"TypeError: Cannot read property 'origin' of undefined",
"    at responseHeaders (/var/task/index.js:32:26)",
"    at /var/task/index.js:124:22",
"    at processTicksAndRejections (internal/process/task_queues.js:95:5)"
]

What could be causing this error?

Here is the code:

/**********************************************************************
*  Upsert Answer item into table
**********************************************************************/
/* POST test
{
"resource": "/",
"path": "/",
"httpMethod": "POST",
"body": "{\"answer\":\"This is my super important answer\",\"questionSlug\":\"this-is-my-super-important-answer\"}"
}
PUT test - make sure to change the ID to one in your database before running or this method will create a new record
{
"resource": "/",
"path": "/",
"httpMethod": "PUT",
"body": "{\"answer\":\"This is my super important answer\",\"negativeVotes\":0,\"positiveVotes\":1,\"id\":\"5ec9957e3f64b70004e7599e\"}"
}
*/
// we need access to the AWS SDK
var AWS = require("aws-sdk");
// we need uuid to generate unique ids
const { v4: uuidv4 } = require("uuid");
//  we need access to DynamoDB and choose the DocumentClient model
var docClient = new AWS.DynamoDB.DocumentClient();
const responseHeaders = (headers) => {
const origin = headers.origin || headers.Origin;
return {
// HTTP headers to pass back to the client
"Content-Type": "application/json",
// the next headers support CORS
"X-Requested-With": "*",
"Access-Control-Allow-Headers":
"Content-Type,X-Amz-Date,Authorization,X-Api-Key,x-requested-with",
"Access-Control-Allow-Origin": origin,
"Access-Control-Allow-Methods": "OPTIONS,*",
Vary: "Origin", // for proxies
// the "has-cors" library used by the Angular application wants this set
"Access-Control-Allow-Credentials": "true",
};
};
exports.handler = async (event) => {
// get the HTTP Method used
var httpMethod = event.httpMethod;
// get the HTTP body sent
var payload = JSON.parse(event.body);
// time to prepare the upsert
const paramQuery = async () => {
// define our query
let params = {
TableName: "Answer",
Key: { id: "" },
UpdateExpression: "set #qi = :qi, #a = :a, #nv = :nv, #pv = :pv",
ExpressionAttributeNames: {
// define the attributes used in the update expression
"#qi": "questionId",
"#a": "answer",
"#nv": "negativeVotes",
"#pv": "positiveVotes",
},
ExpressionAttributeValues: {
// set default values
":qi": "",
":a": "",
":nv": 0,
":pv": 0,
},
// this tells DynamoDB to return the new records with all fields, not just the changed ones
// see https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html for
// information on the possible values
ReturnValues: "ALL_NEW",
};
// these three fields can be set during create or update
//  set the answer if there is one
if (payload.answer && payload.answer.trim())
params.ExpressionAttributeValues[":a"] = payload.answer;
//  set the category slug if there is one
if (payload.questionId && payload.questionId.trim())
params.ExpressionAttributeValues[":qi"] = payload.questionId;
if (httpMethod == "PUT") {
// PUTs are updates but the ID is passed as a path paremeter
// lets get the path parameters
let pathParameters = event.pathParameters;
//  set the unique key of the item to be modified
params.Key.id = pathParameters.id;
// these two values are only changed - they are always defaulted during create
//  set the negativeVotes
params.ExpressionAttributeValues[":nv"] = payload.negativeVotes;
//  set the positiveVotes
params.ExpressionAttributeValues[":pv"] = payload.positiveVotes;
} else {
// POSTs are inserts
// create and set the unique key. its a uuid without the '-'
var id = uuidv4().replace(/\-/g, "");
params.Key.id = id;
}
// uncomment the next line to see the parameters as sent to DynamoDB
//console.log(JSON.stringify(params));
// we create a promise to wrap the async DynamoDB execution
return new Promise((resolve, reject) => {
var queryParams = docClient.update(params).promise();
queryParams
.then(function (data) {
resolve({
statusCode: 200,
body: JSON.stringify(data),
// HTTP headers to pass back to the client
headers: responseHeaders(event.headers),
});
})
.catch(function (err) {
reject(err);
});
});
};
// we await our promise here and return the result (see the resolve above)
return await paramQuery();
};

I tried adding quotes around origin in the properties section, and was expecting data returned. But I still got the same error.

答案1

得分: 0

event.headers参数似乎没有值,因为错误提示它未定义。不如再次检查event的结构,尝试使用参数event而不是event.headers

英文:

The argument event.headers seems to have no value as the error says it is undefined. How about checking the structure of event again and trying the argument event instead of event.headers?

答案2

得分: 0

我注释了

const origin = headers.origin || headers.Origin;

"Access-Control-Allow-Origin": origin,

看起来我的问题得到了解决。

英文:

I commented out

const origin = headers.origin || headers.Origin;

and

 "Access-Control-Allow-Origin": origin,

and it looks like my problem was solved.

huangapple
  • 本文由 发表于 2023年6月5日 03:28:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76402089.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定