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

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

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?

  1. /**********************************************************************
  2. * Upsert Answer item into table
  3. **********************************************************************/
  4. /* POST test
  5. {
  6. "resource": "/",
  7. "path": "/",
  8. "httpMethod": "POST",
  9. "body": "{\"answer\":\"This is my super important answer\",\"questionSlug\":\"this-is-my-super-important-answer\"}"
  10. }
  11. PUT test - make sure to change the ID to one in your database before running or this method will create a new record
  12. {
  13. "resource": "/",
  14. "path": "/",
  15. "httpMethod": "PUT",
  16. "body": "{\"answer\":\"This is my super important answer\",\"negativeVotes\":0,\"positiveVotes\":1,\"id\":\"5ec9957e3f64b70004e7599e\"}"
  17. }
  18. */
  19. // we need access to the AWS SDK
  20. var AWS = require("aws-sdk");
  21. // we need uuid to generate unique ids
  22. const { v4: uuidv4 } = require("uuid");
  23. // we need access to DynamoDB and choose the DocumentClient model
  24. var docClient = new AWS.DynamoDB.DocumentClient();
  25. const responseHeaders = (headers) => {
  26. const origin = headers.origin || headers.Origin;
  27. return {
  28. // HTTP headers to pass back to the client
  29. "Content-Type": "application/json",
  30. // the next headers support CORS
  31. "X-Requested-With": "*",
  32. "Access-Control-Allow-Headers":
  33. "Content-Type,X-Amz-Date,Authorization,X-Api-Key,x-requested-with",
  34. "Access-Control-Allow-Origin": origin,
  35. "Access-Control-Allow-Methods": "OPTIONS,*",
  36. Vary: "Origin", // for proxies
  37. // the "has-cors" library used by the Angular application wants this set
  38. "Access-Control-Allow-Credentials": "true",
  39. };
  40. };
  41. exports.handler = async (event) => {
  42. // get the HTTP Method used
  43. var httpMethod = event.httpMethod;
  44. // get the HTTP body sent
  45. var payload = JSON.parse(event.body);
  46. // time to prepare the upsert
  47. const paramQuery = async () => {
  48. // define our query
  49. let params = {
  50. TableName: "Answer",
  51. Key: { id: "" },
  52. UpdateExpression: "set #qi = :qi, #a = :a, #nv = :nv, #pv = :pv",
  53. ExpressionAttributeNames: {
  54. // define the attributes used in the update expression
  55. "#qi": "questionId",
  56. "#a": "answer",
  57. "#nv": "negativeVotes",
  58. "#pv": "positiveVotes",
  59. },
  60. ExpressionAttributeValues: {
  61. // set default values
  62. ":qi": "",
  63. ":a": "",
  64. ":nv": 0,
  65. ":pv": 0,
  66. },
  67. // this tells DynamoDB to return the new records with all fields, not just the changed ones
  68. // see https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html for
  69. // information on the possible values
  70. ReturnValues: "ALL_NEW",
  71. };
  72. // these three fields can be set during create or update
  73. // set the answer if there is one
  74. if (payload.answer && payload.answer.trim())
  75. params.ExpressionAttributeValues[":a"] = payload.answer;
  76. // set the category slug if there is one
  77. if (payload.questionId && payload.questionId.trim())
  78. params.ExpressionAttributeValues[":qi"] = payload.questionId;
  79. if (httpMethod == "PUT") {
  80. // PUTs are updates but the ID is passed as a path paremeter
  81. // lets get the path parameters
  82. let pathParameters = event.pathParameters;
  83. // set the unique key of the item to be modified
  84. params.Key.id = pathParameters.id;
  85. // these two values are only changed - they are always defaulted during create
  86. // set the negativeVotes
  87. params.ExpressionAttributeValues[":nv"] = payload.negativeVotes;
  88. // set the positiveVotes
  89. params.ExpressionAttributeValues[":pv"] = payload.positiveVotes;
  90. } else {
  91. // POSTs are inserts
  92. // create and set the unique key. its a uuid without the '-'
  93. var id = uuidv4().replace(/-/g, "");
  94. params.Key.id = id;
  95. }
  96. // uncomment the next line to see the parameters as sent to DynamoDB
  97. //console.log(JSON.stringify(params));
  98. // we create a promise to wrap the async DynamoDB execution
  99. return new Promise((resolve, reject) => {
  100. var queryParams = docClient.update(params).promise();
  101. queryParams
  102. .then(function (data) {
  103. resolve({
  104. statusCode: 200,
  105. body: JSON.stringify(data),
  106. // HTTP headers to pass back to the client
  107. headers: responseHeaders(event.headers),
  108. });
  109. })
  110. .catch(function (err) {
  111. reject(err);
  112. });
  113. });
  114. };
  115. // we await our promise here and return the result (see the resolve above)
  116. return await paramQuery();
  117. };

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:

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

What could be causing this error?

Here is the code:

  1. /**********************************************************************
  2. * Upsert Answer item into table
  3. **********************************************************************/
  4. /* POST test
  5. {
  6. "resource": "/",
  7. "path": "/",
  8. "httpMethod": "POST",
  9. "body": "{\"answer\":\"This is my super important answer\",\"questionSlug\":\"this-is-my-super-important-answer\"}"
  10. }
  11. PUT test - make sure to change the ID to one in your database before running or this method will create a new record
  12. {
  13. "resource": "/",
  14. "path": "/",
  15. "httpMethod": "PUT",
  16. "body": "{\"answer\":\"This is my super important answer\",\"negativeVotes\":0,\"positiveVotes\":1,\"id\":\"5ec9957e3f64b70004e7599e\"}"
  17. }
  18. */
  19. // we need access to the AWS SDK
  20. var AWS = require("aws-sdk");
  21. // we need uuid to generate unique ids
  22. const { v4: uuidv4 } = require("uuid");
  23. // we need access to DynamoDB and choose the DocumentClient model
  24. var docClient = new AWS.DynamoDB.DocumentClient();
  25. const responseHeaders = (headers) => {
  26. const origin = headers.origin || headers.Origin;
  27. return {
  28. // HTTP headers to pass back to the client
  29. "Content-Type": "application/json",
  30. // the next headers support CORS
  31. "X-Requested-With": "*",
  32. "Access-Control-Allow-Headers":
  33. "Content-Type,X-Amz-Date,Authorization,X-Api-Key,x-requested-with",
  34. "Access-Control-Allow-Origin": origin,
  35. "Access-Control-Allow-Methods": "OPTIONS,*",
  36. Vary: "Origin", // for proxies
  37. // the "has-cors" library used by the Angular application wants this set
  38. "Access-Control-Allow-Credentials": "true",
  39. };
  40. };
  41. exports.handler = async (event) => {
  42. // get the HTTP Method used
  43. var httpMethod = event.httpMethod;
  44. // get the HTTP body sent
  45. var payload = JSON.parse(event.body);
  46. // time to prepare the upsert
  47. const paramQuery = async () => {
  48. // define our query
  49. let params = {
  50. TableName: "Answer",
  51. Key: { id: "" },
  52. UpdateExpression: "set #qi = :qi, #a = :a, #nv = :nv, #pv = :pv",
  53. ExpressionAttributeNames: {
  54. // define the attributes used in the update expression
  55. "#qi": "questionId",
  56. "#a": "answer",
  57. "#nv": "negativeVotes",
  58. "#pv": "positiveVotes",
  59. },
  60. ExpressionAttributeValues: {
  61. // set default values
  62. ":qi": "",
  63. ":a": "",
  64. ":nv": 0,
  65. ":pv": 0,
  66. },
  67. // this tells DynamoDB to return the new records with all fields, not just the changed ones
  68. // see https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html for
  69. // information on the possible values
  70. ReturnValues: "ALL_NEW",
  71. };
  72. // these three fields can be set during create or update
  73. // set the answer if there is one
  74. if (payload.answer && payload.answer.trim())
  75. params.ExpressionAttributeValues[":a"] = payload.answer;
  76. // set the category slug if there is one
  77. if (payload.questionId && payload.questionId.trim())
  78. params.ExpressionAttributeValues[":qi"] = payload.questionId;
  79. if (httpMethod == "PUT") {
  80. // PUTs are updates but the ID is passed as a path paremeter
  81. // lets get the path parameters
  82. let pathParameters = event.pathParameters;
  83. // set the unique key of the item to be modified
  84. params.Key.id = pathParameters.id;
  85. // these two values are only changed - they are always defaulted during create
  86. // set the negativeVotes
  87. params.ExpressionAttributeValues[":nv"] = payload.negativeVotes;
  88. // set the positiveVotes
  89. params.ExpressionAttributeValues[":pv"] = payload.positiveVotes;
  90. } else {
  91. // POSTs are inserts
  92. // create and set the unique key. its a uuid without the '-'
  93. var id = uuidv4().replace(/\-/g, "");
  94. params.Key.id = id;
  95. }
  96. // uncomment the next line to see the parameters as sent to DynamoDB
  97. //console.log(JSON.stringify(params));
  98. // we create a promise to wrap the async DynamoDB execution
  99. return new Promise((resolve, reject) => {
  100. var queryParams = docClient.update(params).promise();
  101. queryParams
  102. .then(function (data) {
  103. resolve({
  104. statusCode: 200,
  105. body: JSON.stringify(data),
  106. // HTTP headers to pass back to the client
  107. headers: responseHeaders(event.headers),
  108. });
  109. })
  110. .catch(function (err) {
  111. reject(err);
  112. });
  113. });
  114. };
  115. // we await our promise here and return the result (see the resolve above)
  116. return await paramQuery();
  117. };

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

我注释了

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

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

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

英文:

I commented out

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

and

  1. "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:

确定