在官方的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
答案 0 :(得分:1)
来自domain模块官方文档:
根据 throw 在JavaScript中的工作原理的本质,几乎从来没有任何方法可以安全地“拾取你离开的地方”,不会泄漏引用,或者创建其他类型的未定义的脆弱状态。
响应抛出错误的最安全方法是关闭进程......
对我而言,这意味着当您的NodeJS应用程序中出现错误时,您就不幸地完成了。如果您确实关心应用程序的工作方式并且结果对您很重要,那么最好的办法是终止该过程并重新启动它。然而,在最后几毫秒,你可以对其他客户更好,让他们完成他们的工作,对新客户说抱歉,如果你想要记录几件事,然后杀死这个过程并再次启动它。
这就是NodeJS域模块文档示例中的确切情况。
答案 1 :(得分:0)
让我们将您的Web应用程序/服务器视为状态机。
除非您的应用程序非常小,否则您不太可能知道您的计算机可能处于的每个状态。 当您收到错误时,您有两种选择:
1)检查错误并决定做什么,或
2)忽略它。
在第一种情况下,您可以优雅地从一种状态更改为另一种状态。在第二种情况下,您不知道您的机器处于什么状态,因为您没有看到错误是什么。从本质上讲,您机器的状态现在是“未定义的”。
正是由于这个原因,如果错误一直传播到事件循环,NodeJS建议终止进程。再说一次,对于宠物项目和小型应用程序来说,这种程度的赦免可能是过度的,所以你的解决方案也很好。
但想象一下,如果你正在写一个银行软件;总有一天你得到一个你从未见过的错误,你应用简单忽略它并发送500;但每次有人输掉10万美元。在这里,我想确保没有任何错误到达事件循环,如果确实如此,请使用详细的堆栈跟踪终止进程以供以后分析。