为什么我收到错误“UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性‘forEach’”?

时间:2021-03-01 16:06:25

标签: javascript node.js amazon-web-services es6-promise amazon-textract

我有一个 index.js、gettext.js 和 extract.js。

index.js

app.post("/anaData", async function(req, res) {
  const someData = await docExtract(req.body['file_name'])
  const data = await getData(someData)
  .....
 ....
}

gettext.js

async function docExtract (file_name) {
  return new Promise(resolve => {
     var file_params = {
       Document: {
         S3Object: {
           Bucket: bucket_name,
           Name: filename
         }
       },
       FeatureTypes: ['TABLES'],
     }
     
     textract.analyzeDocument(file_params, (err, data) => {
       if (err) {
         return resolve(err)
       } else {
         resolve(data)
       }
     })
   })
 }
 module.exports = docExtract

extract.js

async function getData(data) {
    const blocks = data['Blocks']
  
    const blocksMap = {}
    const tableBlocks = []
  
    blocks.forEach(block => {  //At this point the error is generated: TypeError: Cannot read property 'forEach' of undefined"
      blocksMap[block['Id']] = block
  ....
....
}
  module.exports = getData

我正在发送正确的 json 数据。我已经检查过 req.body['file_name'] 是可访问的。问题似乎与 docExtract 函数返回一个承诺有关,但我似乎无法理解我该怎么做。任何帮助将不胜感激。

错误信息如下:

UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'forEach' of undefined
    at extract (path\to\getData.js:75:12)
    at path\to\index.js:28:22
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

3 个答案:

答案 0 :(得分:2)

<块引用>

无法读取属性“forEach”...

错误表明它正在尝试读取属性 forEach。这意味着这个表达式:

blocks.forEach
<块引用>

...未定义的

...这意味着 blocks 未定义。这意味着当您分配值时:

const blocks = data['Blocks']

...data['Blocks'] 的值为 undefined

因为 getData 是一个 async function,所以它返回一个 Promise。如果函数抛出错误,并且它确实抛出了错误(尝试读取 forEach 值的 undefined 属性),则承诺变为拒绝。 “UnhandledPromiseRejectionWarning”意味着 getData 的调用者没有处理这些拒绝。如果您将 await 包装在 try/catch 中,您可以捕获 getData 抛出的任何错误并对其执行一些有用的操作,例如发送 HTTP 错误响应。

所以希望这可以解释错误““UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'forEach' of undefined”' 的含义。

为了避免错误:

  1. 为避免未经处理的拒绝,请确保在调用 getData() 或任何其他异步函数时等待结果并捕获错误。如果您不这样做,那么任何预期或意外的错误都将无法处理。
  2. 为避免读取未定义值的属性,请确保您访问的数据实际上是您期望的格式。在这种情况下,看起来 data['Blocks'] 是未定义的,所以您要么没有获得您期望的数据,要么您错误地访问了它。尝试记录 data 以查看您实际得到了什么。顺便说一句,data.Blocksdata['Blocks'] 等价,并且比 SELECT CustomerID, CompanyName, Region FROM Customers ORDER BY (CASE WHEN Region IS NULL THEN 1 ELSE 0 END), Region, CompanyName 输入更少。

答案 1 :(得分:1)

我不是 js 专家,但根据我的经验,UnhandledPromiseRejectionWarning 在这种情况下与 await 发生是因为 await 是 promise 处理的简短版本,但只有 {{1 }} 部分。

即如果在 promise 函数中抛出了一些异常,或者如果 promise resolves,那么 reject 不会处理。

我有根据的猜测是 await 的回调 textract.analyzeDocument() 部分只是拒绝它。

答案 2 :(得分:0)

这是一个非常愚蠢的错误导致错误。 bucket_name 变量被环境变量替换,gettext.js 和环境文件中的变量名不同。