4

Nodejs 的默认行为是在错误进入主事件循环时关闭。该手册强烈建议不要覆盖此行为(例如,通过process.on('uncaughtException)。

给出的解释是:

未处理的异常意味着您的应用程序 - 以及扩展的 node.js 本身 - 处于未定义状态。盲目恢复意味着任何事情都可能发生。

升级系统时,将恢复视为拔掉电源线。十次有九次什么都没有发生——但第十次,你的系统崩溃了。

有人可以详细说明一下吗?Chrome 使用与 node 相同的 V8 引擎,默认情况下会在未捕获的错误后恢复其事件循环,AFAIK 这不会导致任何问题。因此,V8 无法从未捕获的异常中优雅地恢复似乎没有任何内在原因。节点内部是否存在与 Chrome 不同的行为?

4

1 回答 1

1

答案与引擎自行重启的能力没有任何关系。

它与您自己的应用程序代码有关。如果发生未处理的异常,则本质上无法理解应用程序的状态。如果有,那么它就不会是一个未处理的异常。而且,如果你不知道你的状态,那么你就不能确定更多未处理的异常不会继续发生,随着时间的推移,很可能会导致更糟糕的问题(因为意外状态会级联成越来越多的意外状态) )。

想象一下这是在服务器上运行的代码(因为它根本不是特定于 node.js):

start process
open two server sockets
process incoming requests

如果您在不处理异常的情况下无法打开第二个服务器套接字,那么您的应用程序很可能无法运行。在下一个逻辑步骤重新启动线程也可能无法正常工作。重启引擎并不能合理关闭一个socket,也不太可能修复第二次失败的原因(很可能端口已经在使用中),如果确实关闭了成功打开的socket,那么最好重启应用程序,以便可以重新打开它(否则它会变得更糟)。

这可能是一个明显的例子,但现在假设您是一个图形应用程序(例如,一个游戏):

start process
load models
handle state (until closing)
   draw screen

如果任何模型在没有异常处理的情况下加载失败,则该过程无法合理地继续,因为它只会在绘图时导致更多错误。

在某些情况下,从未处理的异常中恢复是合理的。在大多数客户端 GUI 框架中,都有一种注册未处理异常的方法,它允许重新启动事件线程(GUI 线程),类似于 Chrome 的 V8 恢复。这是危险的,因为无法保证恢复;导致未处理异常的任何原因仍可能在内存中,并准备在下次使用时再次引发异常。但是,如果出现此类异常,开发良好的应用程序也可能小到足以将其自身擦干净。此类处理程序(处理未处理的异常)的最佳用途是记录异常以便修复问题。

换一种说法:假设发生了一个您没有在任何地方的应用程序中处理的异常。你能做些什么来修复它,这样它就不会在代码的下一次传递中发生?安全地回答这意味着您知道是什么原因造成的,这意味着 A)它不应该被未经处理并且 B)它是孤立的。

唯一可以保证的安全重置是从头开始,这意味着重新启动应用程序。

于 2013-09-24T05:16:37.427 回答