Express.js - 在MongoDB中找不到记录时显示自定义404页面

pow*_*boy 3 mongodb node.js express

我正在使用node-mongodb-native驱动程序.我试过了

collection.findOne({email: 'a@mail.com'}, function(err, result) {
  if (!result) throw new Error('Record not found!');
});
Run Code Online (Sandbox Code Playgroud)

但错误是由mongodb驱动程序捕获并且快速服务器终止.

这种情况的正确方法是什么?

===编辑===

我在app.js中有以下代码

app.configure('development', function() {
    app.use(express.errorHandler({dumpExceptions: true, showStack: true}));
});

app.configure('production', function() {
    app.use(express.errorHandler());
});
Run Code Online (Sandbox Code Playgroud)

相关代码 node_modules/mongodb/lib/mongodb/connection/server.js

connectionPool.on("message", function(message) {
    try {
        ......
    } catch (err) {
      // Throw error in next tick
      process.nextTick(function() {
        throw err; // <-- here throws an uncaught error
      })
    }      
});
Run Code Online (Sandbox Code Playgroud)

fre*_*ish 6

正确的用法不是抛出错误,而是将其传递next函数.首先定义错误处理程序:

app.error(function (err, req, res, next) {
    res.render('error_page.jade');
})
Run Code Online (Sandbox Code Playgroud)

(这是关于error被剥夺的说法?我对此一无所知.但即便如此,你也可以使用use.机制仍然是相同的.).

现在在您的路线中,您将错误传递给处理程序,如下所示:

function handler(req, res, next) {
    collection.findOne({email: 'a@mail.com'}, function(err, result) {
        if (!result) {
            var myerr = new Error('Record not found!');
            return next(myerr); // <---- pass it, not throw it
        }
        res.render('results.jade', { results: result });
    });
};
Run Code Online (Sandbox Code Playgroud)

确保之后没有其他代码(与响应相关)被触发next(myerr);(这就是我在return那里使用的原因).

旁注: Express不能很好地处理异步操作中抛出的错误(实际上,它们有点,但这不是你需要的).这可能会导致您的应用崩溃 捕获它们的唯一方法是使用

process.on('uncaughtException', function(err) {
    // handle it here, log or something
});
Run Code Online (Sandbox Code Playgroud)

但这是一个全局异常处理程序,即您不能使用它将响应发送给用户.