【发布时间】:2015-01-31 06:30:16
【问题描述】:
我无法理解如何处理似乎是 express 的一个非常基本的方面。如果我有一些代码在异步回调中引发异常,则我无法捕获该异常,因为在回调运行时 try/catch 块不再在范围内。在这些情况下,浏览器将挂起,直到它最终放弃声明服务器无响应。这是非常糟糕的用户体验。我宁愿能够立即向客户端返回 500 错误。默认的快速错误处理程序显然不能处理这种情况。下面是一些示例代码:
var express = require("express");
var app = express();
app.use(app.router);
//express error handler (never called)
app.use(function(err, req, res, next) {
console.log(err);
res.send(500);
});
app.get("/test", function(req, res, next) {
require("fs").readFile("/some/file", function(err, data) {
a.b(); //blow up
});
});
app.listen(8888);
在上面的代码中,a.b() 行抛出了“ReferenceError: a is not defined”异常。定义的错误处理程序永远不会被调用。请注意,在这种情况下 fs.readFile() 返回的 err 对象为空,因为文件已被正确读取。错误是异步处理程序中的代码。
我已经阅读了this post 关于使用节点的 uncaughtExpception 的内容,但 the documentation 说不要使用该方法。即使我确实使用了它,我将如何将 500 响应发送回用户?快速响应对象不再供我使用。
那么你如何处理这种情况呢?
【问题讨论】:
-
为什么会在回调中抛出错误?更有可能的是,MongooseObject 会在内部抛出一个错误,您可以在其中捕获它,然后
callback(err)。现在上面显示的回调有一个虚假的错误对象,您可以发送 500 响应。 -
如果 Mongoose 遇到它不回调错误的情况......嗯我不知道也许你可以制作一个 setTimeout 包装器。但我希望所有错误都会立即传递给回调
-
我担心的不是 Mongoose,我只是用它来调用异步函数。我更担心我自己的代码会做一些愚蠢的事情并导致抛出异常。我将更新示例代码以使其更加清晰。
-
为什么不把 try/catch 块放在回调里面,把你关心的那部分代码包装起来呢?您是否正在寻找一个全球性的包罗万象以避免在任何地方这样做?
-
是的,我不想在我拥有的每个异步代码块中都放置尝试捕获,这将是数百个。不过,将它放在每个顶级快递处理程序中可能没问题。