1

在 NodeJS 官方文档中,有一个代码示例,当域中出现异常时,进程会尝试正常退出(它关闭连接,等待一段时间等待其他请求,然后退出)。

但是为什么不发送 500 错误并继续工作呢?

在我的应用程序中,当用户输入无效时,我想抛出一些预期的错误(如 FrontEndUserError),并在中间件的某处捕获这些异常以向客户端发送漂亮的错误消息。使用域很容易实现,但是这有什么陷阱吗?

app.use (err, req, res, next) ->
  if err instanceof FrontEndUserError
    res.send {error: true, message: err.message}
  else
    log err.trace
    res.send 500
4

2 回答 2

1

来自模块官方文档:

由于throw在 JavaScript 中的工作原理,几乎没有任何方法可以安全地“从上次中断的地方继续”,而不会泄漏引用或创建其他类型的未定义的脆弱状态。

响应抛出错误的最安全方法是关闭进程...

对我来说,这意味着当你的 NodeJS 应用程序中出现错误时,很遗憾你就完蛋了。如果您确实关心应用程序的工作方式并且结果对您很重要,那么最好的选择是终止该进程并重新启动它。然而,在最后几毫秒,你可以对其他客户更好,让他们完成他们的工作,对新客户说对不起,如果你愿意,可以记录一些事情,然后终止进程并重新启动它。

这正是 NodeJS 域模块的文档示例中发生的事情。

于 2013-07-24T19:34:32.007 回答
0

让我们将您的 Web 应用程序/服务器视为状态机。

除非您的应用程序非常小,否则您不太可能碰巧知道您的机器可能处于的每个状态。当您遇到错误时,您有两种选择:

1)检查错误并决定做什么,或者

2)忽略它。

在第一种情况下,您可以优雅地从一种状态更改为另一种状态。在第二种情况下,您不知道您的机器处于什么状态,因为您没有费心去查看错误是什么。本质上,您的机器状态现在是“未定义”。

正是出于这个原因,NodeJS 建议如果错误一直传播到事件循环,则终止该进程。再说一次,这种级别的赦免对于宠物项目和小型应用程序来说可能是过分的,所以你的解决方案也很好。

但是想象一下,如果你正在编写一个银行软件;有一天你会收到一个你从未见过的错误,你的应用程序会忽略它并发送一个 500;但每次有人损失 10 万美元。在这里,我想确保没有错误到达事件循环,如果确实如此,则使用详细的堆栈跟踪终止进程以供以后分析。

于 2013-05-27T09:38:38.697 回答