不要试图对未处理的异常做任何花哨的事情。让服务器死掉。
通常,如果路由处理程序抛出异常,Express 将简单地捕获它并向客户端返回 HTTP 500。由于 Express 捕获了异常,因此您的服务器不会崩溃。
导致服务器宕机的通常情况是在回调中抛出异常;例如:
app.get('/foo', function(req, res) {
db.query(..., function(err, r) {
throw new Error(); // oops, we'll crash
});
});
因为回调自然在 Express 路由器调用堆栈之外执行,所以无法将其与特定请求相关联。但是,您可以防范这种情况:
app.get('/foo', function(req, res, next) {
db.query(..., function(err, r) {
try {
throw new Error();
} catch(ex) {
next(ex);
}
});
});
Expressnext
函数将错误作为其第一个参数。如果您next
使用错误参数调用,它将停止处理路由并寻找错误处理程序,或者只返回 500。
当然,将所有内容都包含在try
/catch
中可能有点过头了。大多数事情实际上并没有引发异常。仅当您知道某些东西可能会抛出时,您才应该这样做。否则,您可能会通过吞咽异常而最终陷入非常难以调试不一致状态的状态。
请务必记住,一旦引发意外异常,您的应用程序就处于未定义状态。问题请求可能永远不会完成,并且您的应用程序永远不会重新启动。或者可能发生任何其他奇怪的事情。(是数据库问题吗?文件系统?内存损坏?)
这些情况很难诊断,更不用说调试了。快速失败、崩溃和快速重启服务器更安全,可以说更好。是的,任何碰巧连接的客户端都会被切断,但它们很容易重试。
如果您担心可用性,请使用集群模块,这样您就可以运行多个(通常是多个 CPU 内核)服务器进程,并且一个崩溃不会导致整个站点崩溃。