【问题标题】:ElasticSearch-js { body } is undefinedElasticSearch-js { body } 未定义
【发布时间】:2021-03-23 00:50:03
【问题描述】:

运行 AWS lambda 函数将数据推送到 Elasticsearch 实例时出现此错误 如果我从节点模块中手动删除 { body },我可以让它运行,但我找不到它为什么一直出错。

我的代码

client.helpers.bulk({
        datasource: docs,
        onDocument(doc) {
            return {
                index: { _index: index , _id: doc.id },
                body: doc.body
           }
        },
        onDrop(doc) {
            console.log("failed to index ", doc.key);
        },
        retries: 5,
        flushBytes: 1000000,
        wait: 10000

    })

错误

{
    "errorType": "Runtime.UnhandledPromiseRejection",
    "errorMessage": "TypeError: Cannot destructure property 'body' of 'undefined' as it is undefined.",
    "reason": {
        "errorType": "TypeError",
        "errorMessage": "Cannot destructure property 'body' of 'undefined' as it is undefined.",
        "stack": [
            "TypeError: Cannot destructure property 'body' of 'undefined' as it is undefined.",
            "    at /var/task/node_modules/@elastic/elasticsearch/lib/Helpers.js:679:81"
        ]
    },
    "promise": {},
    "stack": [
        "Runtime.UnhandledPromiseRejection: TypeError: Cannot destructure property 'body' of 'undefined' as it is undefined.",
        "    at process.<anonymous> (/var/runtime/index.js:35:15)",
        "    at process.emit (events.js:314:20)",
        "    at process.EventEmitter.emit (domain.js:483:12)",
        "    at processPromiseRejections (internal/process/promises.js:209:33)",
        "    at processTicksAndRejections (internal/process/task_queues.js:98:32)"
    ]
}

【问题讨论】:

  • 这个函数怎么调用? index.js 35:15到底在哪里?
  • 不确定,index.js 只有 30 行
  • onDocument 中尝试console.log(doc)return 语句之前,看看哪个文档失败了。
  • 我已经这样做了,它会记录所有文档,然后失败,或者至少多达 170 个,我已将其缩减到 10 个进行测试,但在记录所有文档后它就失败了。跨度>
  • 我遇到了同样的错误(使用 AWS Lambda 和 AWS Elasticsearch 连接器 9.0.3)。在我的情况下,超过 170 的索引似乎是成功的。你找到解决办法了吗?

标签: node.js elasticsearch aws-lambda aws-elasticsearch


【解决方案1】:

在引用@opensearch-project/opensearch(这是一个elasticsearch-js 客户端分支)并使用client.helpers.bulk 帮助程序时,我也遇到了这个错误。这与 aws-elasticsearch-connector 一起用于实施 AWS SigV4 签名的 API 请求。

错误信息如下:

TypeError: Cannot destructure property 'body' of 'undefined' as it is undefined.
      at node_modules/@opensearch-project/opensearch/lib/Helpers.js:704:93

这很烦人,而且我没有心情实现自己的 OpenSearch 客户端并直接与 API 交互,所以我深入挖掘并发现了问题。

如何重现错误?

我创建了一个独立的测试来说明问题。希望通过这种方式可以轻松重现。

import { Client } from '@opensearch-project/opensearch';
import * as AWS from 'aws-sdk';

// My fork of https://www.npmjs.com/package/aws-elasticsearch-connector capable of signing requests to AWS OpenSearch
// @opensearch-project/opensearch is not yet capable of signing AWS requests
const createAwsElasticsearchConnector = require('../modules/aws-oss-connector');

const domain =
  'PUT_YOUR_DOMAIN_URL_HERE.es.amazonaws.com';
const index = 'YOUR_TEST_INDEX_NAME';

const bootstrapOSSClient = (): Client => {
  const ossConnectorConfig = createAwsElasticsearchConnector(AWS.config);
  const client = new Client({
    ...ossConnectorConfig,
    node: `https://${domain}`,
  });

  return client;
};

const main = async (): Promise<void> => {
  try {
    console.info('Starting processing');

    // TEST DEFINITION
    const input = [
      { id: '1', name: 'test' },
      { id: '2', name: 'test 2' },
    ];

    const client = bootstrapOSSClient();

    const response = await client.helpers.bulk({
      datasource: input,
      onDocument(doc: any) {
        console.info(`Processing document #${doc.id}`);
        return {
          index: { _index: index, _id: doc.id },
        };
      },
    });

    console.info(`Indexed ${response.successful} documents`);

    // END TEST DEFINITION

    console.info('Finished processing');
  } catch (error) {
    console.warn(`Error in main(): ${error}`);
  }
};

try {
  main().then(() => {
    console.info('Exited main()');
  });
} catch (error) {
  console.warn(`Top-level error: ${error}`);
}

结果是

$ npx ts-node ./.vscode/test.ts
Starting processing
Processing document #1
Processing document #2
(node:39232) UnhandledPromiseRejectionWarning: TypeError: Cannot destructure property 'body' of 'undefined' as it is undefined.
    at D:\Development\eSUB\Coronado\git\platform\node_modules\@opensearch-project\opensearch\lib\Helpers.js:704:93
(Use `node --trace-warnings ...` to show where the warning was created)
(node:39232) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:39232) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Indexed 2 documents
Finished processing
Exited main()

单步执行代码我能够拦截对node_modules/@opensearch-project/opensearch/lib/Helpers.js:704:93 where 的单个调用

  • client.bulk() 被调用
  • \opensearch\api\api\bulk.js中调用bulkApi()并成功返回
  • await finish()\opensearch\lib\Helpers.js:559 中被调用
  • \opensearch\lib\Transport.js 内部调用prepareRequest(),以return transportReturn 结束
  • 这最终以request():177 调用
return p.then(onFulfilled, onRejected)

当时pnull。这导致我在 AWS Transport 类中的回调负责签署请求以回调到带有未定义第二个参数的 Helper.js tryBulk(),从而导致 Cannot destructure property 'body' 错误。

预期的行为是什么?

Transport.jsrequest() call 中传递回调时,请求的实现显然不会导致null p 承诺问题。我在opensearch-js 存储库中记录了bug

解决方法

至少对我来说,这看起来只有在使用自定义 AWS 签名请求连接器实施时才会出现问题。如果您的情况类似,一个快速的解决方法是修改该实现Transport 类。这是一个特定于aws-elasticsearch-connector 的快速而肮脏的修补程序。

你需要修改AmazonTransport.js from

 class AmazonTransport extends Transport {
    request (params, options = {}, callback = undefined) {
      ...

      // Callback support
      awaitAwsCredentials(awsConfig)
        .then(() => super.request(params, options, callback))
        .catch(callback)
    }

      // Callback support
      // Removed .then() chain due to a bug https://github.com/opensearch-project/opensearch-js/issues/185
      // .then() was calling then (onFulfilled, onRejected) on transportReturn, resulting in a null value exception
      awaitAwsCredentials(awsConfig).then();

      try {
          super.request(params, options, callback);
      } catch (err) {
          callback(err, { body: null });
      }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-09
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    相关资源
    最近更新 更多