【问题标题】:Express.js - display a custom 404 page when a record is not found in MongoDBExpress.js - 在 MongoDB 中找不到记录时显示自定义 404 页面
【发布时间】:2012-07-16 04:12:36
【问题描述】:

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

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

但是mongodb驱动发现了错误,express server被终止了。

这个案例的正确方法是什么?

=== 编辑===

我在 app.js 中有下面的代码

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

app.configure('production', function() {
    app.use(express.errorHandler());
});

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
      })
    }      
});

【问题讨论】:

  • app 是什么对象?它是http 服务器、express 服务器还是其他什么?

标签: node.js mongodb express


【解决方案1】:

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

app.error(function (err, req, res, next) {
    res.render('error_page.jade');
})

(关于 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 });
    });
};

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

旁注: Express 无法很好地处理异步操作中引发的错误(嗯,实际上它们有些处理,但这不是您需要的)。这可能会使您的应用程序崩溃。捕获它们的唯一方法是使用

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

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

【讨论】:

  • 这行得通!关于 app.error 在 3.x 中被弃用,我在某处读过它,但我忘记了它在哪里。在旁注中,您说“Express 无法很好地处理异步操作中引发的错误”。那么,如果我在旁注之前使用您的解决方案,会有任何潜在问题吗?
  • 为什么你调用next而不是直接从回调中渲染错误页面?我可以理解错误处理程序是否很大,但是对于像这样的简单案例有什么好处吗?只是想提高我的快递知识。 :)
  • @meloncholy - 我想要一个地方来处理所有错误,包括运行时错误和在应用程序中明确抛出的错误。
  • @meloncholy 因为您可能希望在许多路由中抛出相同的异常。使用错误处理程序处理错误页面会更容易。
  • @powerboy 不会有任何问题,因为在解决方案中您没有抛出异常,而是通过了。 :) 只有在异步代码中抛出异常时才会出现问题。
【解决方案2】:

我猜错误没有被捕获。您是否使用 Express 错误处理程序?比如:

app.error(function (err, req, res, next) {
 res.render('error-page', {
  status: 404
 });

更多关于 Express 中的错误处理:http://expressjs.com/guide.html#error-handling

【讨论】:

  • app.error 已弃用。请改用app.use。无论如何,两者都不适用于我的情况。可能和mongodb驱动有关。
【解决方案3】:

在检查 mongodb 错误方面,使用 '!error' 表示成功,而不是使用 '!result' 表示错误。

collection.findOne({email: 'a@mail.com'}, function(err, result) {
    if (!error) {
        // do good stuff;
    } else {
        throw new Error('Record not found!');
    }
});

至于自定义 404,我还没有在 node 和 express 中这样做,但我想它会涉及“app.router”。

【讨论】:

  • 我试过这个。实际上,如果 mongodb 找不到记录,result 将变为 nullerr 未设置。
  • 奇怪。我刚刚用我的应用程序尝试了这个 - 它给我一个不存在但 mongodb 和 express 继续运行的记录的错误。我没有做任何处理,所以它给了我一个 500 页的堆栈跟踪。
猜你喜欢
  • 1970-01-01
  • 2021-08-23
  • 2015-11-06
  • 1970-01-01
  • 2019-09-14
  • 2015-01-14
  • 2013-07-27
  • 1970-01-01
  • 2018-01-05
相关资源
最近更新 更多