由于错误处理承诺而导致的套接字挂断
Posted
技术标签:
【中文标题】由于错误处理承诺而导致的套接字挂断【英文标题】: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。你在这方面有什么进展吗?我试图在下面提供答案。你有没有机会检查一下,这有意义吗?如果我的回答有用,请点击它左侧的点赞按钮 (▲)。如果它回答了您的问题,请单击复选标记 (✓) 接受它。这样其他人就知道你得到了(足够的)帮助。 我离开了。似乎没有任何效果。 我做了一个工作来解决这个任务。而不是计算和处理只在云中失败的承诺,在模拟器中一切正常。所以我所做的就是在模拟器中完成所有工作,并在云中创建一个端点,只是为了创建作为有效负载传递的记录。 【参考方案1】:socket hang up 有两种情况:
当您是客户时
当您作为客户端向远程服务器发送请求时,没有及时收到响应。您的套接字已结束,这会引发此错误。您应该捕获此错误并决定如何处理它:是否重试请求、将其排队以备后用等。
当您是服务器/代理时
当您作为服务器(可能是代理服务器)收到来自客户端的请求,然后开始对其采取行动(或将请求中继到上游服务器),在您准备好响应之前,客户端决定取消/中止请求。
我建议您尝试和测试一些可能帮助您解决 ECONNRESET 问题的可能性:
如果您可以访问源数据库,您可以尝试查找 那里有一些日志或指标。也许你正在超载 服务。
用于开发的快速而肮脏的解决方案:使用longjohn,你会很长 将包含异步操作的堆栈跟踪。清洁和 正确的解决方案:从技术上讲,在节点中,每当您发出“错误”时 事件并且没有人听它,它会抛出错误。让它 不要扔,在上面放一个监听器并自己处理。这样你 可以用更多信息记录错误。
您也可以设置 NODE_DEBUG=net 或使用strace。他们都为您提供 节点在内部做什么。
您可以重新启动服务器并再次运行连接,也许 您的服务器崩溃或拒绝连接很可能被阻止 用户代理。
您也可以尝试在本地运行此代码,而不是在云端运行 函数来查看是否有不同的结果。有可能是 RSG/google 网络正在以某种方式干扰。
您还可以查看 GitHub issue 和 *** thread 以查看 ECONNRESET 问题的常见修复,看看是否 这些有助于解决问题。
【讨论】:
以上是关于由于错误处理承诺而导致的套接字挂断的主要内容,如果未能解决你的问题,请参考以下文章