我如何处理expressjs应用程序中的意外错误以避免停机



如何处理Express应用程序中的意外错误以避免停机?

我的第一个想法是使用try/catch语句来处理意外错误,但这只适用于同步代码。我发现一个可能的选择是使用Node.js的"域模块",然而,事实证明,它是不赞成的,并且将继续不赞成。

目前我正在处理错误,通过使用中间件是由快车生成器提供的。我也在使用一个名为"永远"的过程监控程序。进程监控和Express的中间件是否足以成功地处理意外错误,或者我是否应该考虑其他选项?

坦率地说,您无法处理意外错误。这并不是说你不能处理错误,显然你可以、应该和必须处理错误。我说的是,如果一个错误被处理了,那么程序就会预料到它,这不是意外的,如果程序没有预料到它,那么它就是意外的,所以本质上,如果你处理了意外的错误,你不是在处理意外的错误,你只是在处理错误。

作为开发人员,我们的工作是尽我们所能彻底排除意外错误,尽管我们没有人能完全成功。通过投入和严格的努力,可以达到这样的水平,即代码中确实发生的意外错误非常少,并且至少在一定程度上是可以容忍的。错误处理是一个过程,通常在测试版发布后很长一段时间,甚至在第一个真正的生产版本发布后很长一段时间。在收集数据的过程中,bug/错误会通过版本控制被发现和消除。打补丁,一种技术,旨在继续提高软件的完整性,即使它已经发布了很长时间。

正如您应该已经理解的那样,没有一个修复程序可以处理所有意想不到的错误。作为一名开发者,你应该在制作应用前消除所有编程错误,并尽可能地处理操作错误,这意味着你应该理解什么是编程错误,什么是操作错误。

  • # 1。编程错误:代码本身的错误和/或bug。

  • # 2。操作错误——发生在程序员控制范围之外的地方的错误。错误是由客户端、网络、v8引擎引起的(这也可以是编程的)。

没有明确的方法将每个错误定义为操作或编程,灰色地带确实存在。有一些方法可以帮助我们做出明确的判断。如果您查看代码并发现无法通过编写不同的代码或更多代码来解决错误,则可能不是编程错误。如果您在尝试连接到特定主机时出现错误,而您在其他地方的连接正常,则可能是可操作的。即使应用程序的代码编写得完美无缺,也会发生操作错误,只要确保在确定代码完整性时正确即可。

这里有几个例子:

操作错误
  1. 插座滴
  2. 请求超时
  3. 验证客户端凭证失败
  4. 任何由合法性问题引起的错误

下面是几个例子:编程错误

  1. 传入函数的变量类型无效
  2. 错误/无效语法
  3. 验证客户端凭证失败
  4. 名称冲突

正如我已经指出的那样,理解这两种错误类型的目的是让您作为开发人员可以消除所有错误,您不仅要负责消除错误,而且需要消除错误才能拥有一个像样的工作应用程序。在Node.js应用程序开发的世界里,这是区分英雄和零,女人和女孩,光荣的吉娃娃和大脚怪的部分(好吧,我对吉娃娃有偏见)。

这真的不是一个可以用一行字回答的问题或话题,主要是因为,你不能只用一些第三方NPM API处理所有意想不到的错误,而且还因为学习和知道该做什么不是学习更多JavaScript语法的问题,而是学习每个想要构建坚实,构建良好的Node.js应用程序的开发人员需要知道的范例。

我知道你们中的一些人现在正在说话,认为你有答案,它是如此简单。其实不是。那些使用事件侦听器捕获未捕获/意外错误的人并没有将出色的应用程序(如果有的话)投入生产。我当然希望你工作的任何公司都不要让你发布使用它的代码。对于那些不知道我在说什么的人,它在这个文本块下面。仅供参考,这个页面上已经有建议了,这让我大吃一惊。

//Catch uncaught exceptions
process.on('uncaughtException', function (err) {
// handle the error safely
console.log(err);
});

上面的是不应该做什么的完美例子!!!!!!

如果意外发生错误,正确的做法是将其作为错误对象抛出。不这样做会威胁到整个应用程序的完整性。请记住,当客户端不得不处理由于您没有按照要求做正确的事情而导致的结果时,您将离开您的服务器。使用上述代码片段会威胁服务器的安全性。这包括访问你的服务器所需的信息,你的pem密钥,你的密码,你所有的数据库和数据库数据,最糟糕的是,你存储的任何客户信息,包括你保留的任何信用卡和密码(确保你把这类东西河豚鱼)。当你启动一个以这种方式处理意外错误的应用程序时,一切都处于危险之中。

可能的问题包括:

  1. 在v - 8c++级别上使用和传递的内存引用可能会被搞砸。这可能导致大量内存泄漏。您可能最终没有必要的内存来完成请求,或为此做任何事情。内存泄漏是目前节点社区的一个主要话题,因为开发人员正在花费大量时间调试它们。
  2. 一些事务可能被打开,特别是在内存泄漏期间,错误的请求和数据可能被发送给错误的用户。随机的人可能会收到其他人的会话ID。这是黑客会很快利用的东西,特别是如果涉及到任何财务问题。

实际上还有更多,内存泄漏是一个大问题,尽管试图解决另一个问题会使它变得更糟。你可以把两者都做得更好,作为开发者,你只需要具备完整性,这样你的应用就会具有完整性。

事件发生的原因是为了记录和监控。它实际上默认在运行的每个节点实例中实现,并且是Error对象如何管理通知和关于意外错误的一部分。下面是正确的用法。


process.on('uncaughtExceptionMonitor', (err, origin) => {
MyMonitoringTool.logSync(err, origin);

// if needed pass the error to a function that will throw it...
});

以上是一个来自Node.js网站的例子,在那里你可以进一步了解错误处理和意外错误。

Node.js官方错误处理文档

最后我们讨论错误监视器。对于小型应用程序,错误监视器可能是完成令人满意的工作所需要的全部。知道你是否为错误做了足够多的唯一方法生产过程中出现的意外错误,就是要达到这样的程度,即您觉得所有的操作错误都得到了错误处理,并且所有的编程错误都得到了纠正。然后,您需要一个记录错误的日志系统。您可以建立自己的日志系统或购买一个定期收费。你将需要一个监视器,再一次,你可以从技术上构建一个,对于大多数东西,我建议尝试,但为此我会支付非常小的月费,它会重新启动你的应用程序,如果它崩溃由于意想不到的错误。

上面的答案真的很糟糕,但这里面有一些好的东西。我确实从上面提到的Node网站得到了帮助。我也从这里得到了帮助,这是我一次又一次引用的资源,你也应该这样做。处理节点应用程序中的意外错误

我将永远推荐pm2,因为它有几个很棒的特性。我们在我们的生产网站上使用它,效果很好。启用日志记录来跟踪异常。

http://pm2.keymetrics.io/

PM2允许您轻松管理日志。您可以实时显示所有应用程序日志,刷新它们并重新加载它们。还有不同的方法来配置PM2如何处理您的日志(在不同的文件中分开,合并,使用时间戳…),而无需修改代码中的任何内容。

我已经在我的应用程序中通过在我的"index.js"中列出未捕获的进程错误来处理这个问题。

//Catch uncaught exceptions
process.on('uncaughtException', function (err) {
// handle the error safely
console.log(err);
});

可以结合使用生成器和承诺来使用try-catch。——https://gist.github.com/swarajgiri/16202e32aa4d80d45c62

在捕获错误时,将其传递给server/app.js中的错误处理程序。

// errors handler. 
app.use(function (err, req, res, next) {
if (! err) {
return next();
}
res.status(500);
res.send('500: Internal server error');
});

您仍然需要foreverpm2管理它。

最新更新