【问题标题】:Socket hangup due to wrong handling of promises由于错误处理承诺而导致的套接字挂断
【发布时间】:2021-11-13 14:08:56
【问题描述】:

我有脚本可以将数据从一个平台移动到另一个平台。源数据库只允许在单个请求中获取 100 条记录。所以我创建了一个例程来批量获取 100 个,我猜它工作正常。

现在我尝试处理每条 100 条记录并进行必要的转换(这涉及到 axios 调用以获取某些数据)并在 firebase firestore 中创建一条记录。 现在,当我在 firebase express 节点中运行此迁移时,我的套接字挂断了 ECONNRESET。

我知道这是由于对 promise 的错误处理造成的。

我的代码如下所示:


import { scrollByBatches } from "../helpers/migrations/apiScroll";
import { createServiceLocation } from "../helpers/locations";

const mapServiceLocationData = async (serviceLocation: any, env: string) => {
  try {
    const migratedServiceLocation: any = {
      isMigrated: true,
      id: serviceLocation._id,
    };


    if (serviceLocation.list?.length) {
      await Promise.all(serviceLocation.ids.map(async (id: string) => {
        const { data } = await dbEndPoint.priceMultiplier({ id });  // error says socket hangup on this call
        let multiplierUnit;
        let serviceType;
        if (data.response._id) {
          multiplierUnit = data.response;
          const result = await dbEndPoint.serviceType({ id: multiplierUnit.service_custom_service_type }); // error says socket hangup on this call
          if (result.data.response._id) {
            serviceType = result.data.response.type_text;
            migratedServiceLocation.logs = [...multiplierUnit.history_list_text, ...migratedServiceLocation.logs];
          }
        }
      }));
    }

    await createServiceLocation(migratedServiceLocation); // create record in destination db
  } catch (error) {
    console.log("Error serviceLocation: ", serviceLocation._id, JSON.stringify(error));
  }
  return null; // is this even necessary?
};

export const up = async () => {
  try {
    // get 100 docs from source db => process it.. => fetch next 100 => so on...
    await scrollByBatches(dbEndPoint.serviceLocation, async (serviceLocations: any) => {
      await Promise.all(
          serviceLocations.map(async (serviceLocation: any) => {
            await mapServiceLocationData(serviceLocation);
          })
      );
    }, 100);
  } catch (error) {
    console.log("Error", JSON.stringify(error));
  }
  return null; // is this even necessary?
};

我在 firebase 函数控制台中遇到的错误是:

为了清楚分批获取的外观如下:

const iterateInBatches = async (endPoint: any, limit: number, cursor: number, callback: any, resolve: any, reject: any) => {
  try {
    const result = await endPoint({ limit, cursor });
    const { results, remaining }: any = result.data.response;

    if (remaining >= 0) {
      await callback(results);
    }
    if ((remaining)) {
      setTimeout(() => {
        iterateInBatches(endPoint, limit, (cursor + limit), callback, resolve, reject);
      }, 1000); // wait a second
    } else {
      resolve();
    }
  } catch (err) {
    reject(err);
  }
};

export const scrollByBatches = async (endPoint: any, callback: any, limit: number, cursor: number = 0) => {
  return new Promise((resolve, reject) => {
    iterateInBatches(endPoint, limit, cursor, callback, resolve, reject);
  });
};

我做错了什么?为了便于阅读,我在代码部分添加了 cmets。

谢谢。

【问题讨论】:

  • 嘿VPR。你在这方面有什么进展吗?我试图在下面提供答案。你有没有机会检查一下,这有意义吗?如果我的回答有用,请点击它左侧的点赞按钮 (▲)。如果它回答了您的问题,请单击复选标记 (✓) 接受它。这样其他人就知道你得到了(足够的)帮助。
  • 我离开了。似乎没有任何效果。
  • 我做了一个工作来解决这个任务。而不是计算和处理只在云中失败的承诺,在模拟器中一切正常。所以我所做的就是在模拟器中完成所有工作,并在云中创建一个端点,只是为了创建作为有效负载传递的记录。

标签: javascript node.js firebase promise google-cloud-functions


【解决方案1】:

socket hang up 有两种情况:

当您是客户时

当您作为客户端向远程服务器发送请求时,没有及时收到响应。您的套接字已结束,这会引发此错误。您应该捕获此错误并决定如何处理它:是否重试请求、将其排队以备后用等。

当您是服务器/代理时

当您作为服务器(可能是代理服务器)收到来自客户端的请求,然后开始对其采取行动(或将请求中继到上游服务器),在您准备好响应之前,客户端决定取消/中止请求。

我建议您尝试和测试一些可能帮助您解决 ECONNRESET 问题的可能性:

  • 如果您可以访问源数据库,您可以尝试查找 那里有一些日志或指标。也许你正在超载 服务。

  • 用于开发的快速而肮脏的解决方案:使用longjohn,你会很长 将包含异步操作的堆栈跟踪。清洁和 正确的解决方案:从技术上讲,在节点中,每当您发出“错误”时 事件并且没有人听它,它会抛出错误。让它 不要扔,在上面放一个监听器并自己处理。这样你 可以用更多信息记录错误。

  • 您也可以设置 NODE_DEBUG=net 或使用strace。他们都为您提供 节点在内部做什么。

  • 您可以重新启动服务器并再次运行连接,也许 您的服务器崩溃或拒绝连接很可能被阻止 用户代理。

  • 您也可以尝试在本地运行此代码,而不是在云端运行 函数来查看是否有不同的结果。有可能是 RSG/google 网络正在以某种方式干扰。

  • 您还可以查看 GitHub issuestackoverflow thread 以查看 ECONNRESET 问题的常见修复,看看是否 这些有助于解决问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    相关资源
    最近更新 更多