gpt4 book ai didi

node.js - 如何在别人的API代码中 "catch"the throw er;//Unhandled 'error'事件?

转载 作者:太空宇宙 更新时间:2023-11-03 23:51:06 24 4
gpt4 key购买 nike

我正在使用 npm 中的第 3 方包,该包又连接到 IP 地址 X.X.X.X 上的某些外部 API,并且崩溃并出现以下错误。原因很清楚,网络暂时瘫痪,然后我的整个程序就停止了:

events.js:177
throw er; // Unhandled 'error' event
^

Error: connect ENETUNREACH X.X.X.X:80
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1054:14)
Emitted 'error' event at:
at Socket.socketErrorListener (_http_client.js:410:9)
at Socket.emit (events.js:200:13)
at emitErrorNT (internal/streams/destroy.js:91:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
at processTicksAndRejections (internal/process/task_queues.js:84:9) {
errno: 'ENETUNREACH',
code: 'ENETUNREACH',
syscall: 'connect',
address: 'X.X.X.X',
port: 80
}

我故意不说 npm 上的哪个模块导致了问题,因为我无法控制第 3 方模块作者正在做什么。如果我向他们提示,他们可能会也可能不会修复它,但我的编码生活需要继续。即使我调用的任何代码存在编码错误,它也不应该完全使我的调用脚本崩溃。应该有一种方法可以让我在它完全限制我的风格之前捕获它。

我尝试过的:我仔细地使用错误处理,try/catch围绕任何第3方异步库调用等。示例:

var ThirdPartyModule = require("thirdPartyModule");
try {
await ThirdPartyModule.doIt("some", "params");
} catch (err) {
console.log("Ok so the module call failed. Let's try something else here, but don't abort my script please!");
}

catch 不执行任何操作。每次调用模块并发生连接错误时,它都会用上面的“throw er;”完全淹没我的整个程序。

我的问题是,我可以在对库的调用周围编写哪些额外的“包装”代码来“捕获”不属于我的代码中的任何崩溃,以便我的代码继续执行?

我仍然是 Nodejs 中的菜鸟,所以我认为我错过了一些在这里工作的更大的 NodeJS 概念。我来自 C++ 或 Java,所以每当这些语言中出现崩溃时,我总是可以 catch() 它,所以我很困惑模块如何在我的主脚本中“转义”try/catch。

请注意,我并不是在寻找诸如“您应该确保始终连接到互联网,这就是 ENETUNREACH 的意义所在。”之类的答案。相反,我试图了解如何成为我所调用的“子模块”的主人,即捕获它们的错误,或者如果我不能成为它们的主人,我想了解为什么我想要的东西在 Nodejs 中是不可能的。

谢谢!

编辑:在下面链接的类似问题中,评论者建议添加一个 process.on("uncaughtException") 处理程序。我现在就尝试一下。

如果这是正确的解决方案,请将其作为答案发布并解释基本概念。为什么我不能仅仅依靠 try/catch 这就是改革后的 Java 程序员会做的事情? npm 上模块的作者做了什么才能不将错误传递到他的异步函数中的链上?

编辑2:也许我的问题最终与Catch all uncaughtException for Node js app重复。 - 我希望能得到一个解释,为什么某些深层的崩溃必须像这样在全局范围内被捕获,并且不会渗透到调用者链上。是否是因为第 3 方编码器犯了错误,并且未能将其代码中可能出现的所有可能问题转换为异步代码中正确的 throw

编辑 3:好的,我设法找到了问题所在。我使用的图书馆不是罪魁祸首。它天真地调用并 promise 了一个第四方库(也在 npm 上),该库通过 http.request() 连接到服务器。只是该第四方库的作者忘记安装 request.on('error') 回调,因此当互联网连接出现问题时(永远不会发生,对吧!),就会出现无法处理的情况。第三方库永远不会从第四方库获得预期的“错误”回调,因此永远无法 promise 该错误情况。相反,错误在 nodejs ether 中未得到处理,导致我的整个脚本崩溃。所以有...

最佳答案

绝对不对库内代码的结构做出任何假设,您将陷入以下困境:

process.on('uncaughtException', function (err) {
//do something
});

原因是:如果库自始至终都使用 Promise,那么 try/catch block 就会捕获它。库内抛出错误的部分很可能位于回调内。

异步代码的最佳实践应该是向回调返回错误,返回被拒绝的 Promise 或在异步 block 内抛出,并且永远不要使用回调或原始 Promise 在函数内抛出。然而,这似乎极有可能正是正在发生的事情。此时没有办法优雅地处理错误,只能捕获所有uncaughtException

本质上,在 Promise 或传统异步回调中抛出错误的情况下,代码会抛出同步错误,并且没有同步 try/catch block 来处理它。而且您无法从模块外部注入(inject)。

所以简而言之,该错误没有“适当”的机制可以处理。第三方模块编写者应该感到羞耻。

关于node.js - 如何在别人的API代码中 "catch"the throw er;//Unhandled 'error'事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59463127/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com