2012-07-15 37 views
3

我正在使用node-mongodb-native驱动程序。我试过Express.js - 在MongoDB中未找到记录时显示自定义404页面

collection.findOne({email: '[email protected]'}, function(err, result) { 
    if (!result) throw new Error('Record not found!'); 
}); 

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

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

===编辑===

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

回答

5

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

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

(?。这是什么谈error被depracated我不知道任何事情但是,即使那么你可以只用use的机制仍然是相同的) 。

现在,在你的路线传递错误的处理程序是这样的:

function handler(req, res, next) { 
    collection.findOne({email: '[email protected]'}, 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 
}); 

但是这是一个全球性的异常处理程序,即你不能用它来发送给用户的响应。

+0

This Works!关于'app.error'在3.x中的描述,我在某处读过它,但我忘记了它在哪里。在附注中,你说“异步操作引发的错误不能很好地通过Express处理”。那么,如果我在附注前使用您的解决方案,是否有任何潜在的问题? – powerboy 2012-07-15 20:20:18

+0

为什么你调用'next'而不是直接从回调中渲染错误页面?我可以理解,如果错误处理程序是巨大的,但对于这样的简单情况是否有优势?只是想提高我的表达知识。 :) – meloncholy 2012-07-15 20:20:41

+1

@meloncholy - 我想要一个地方来处理所有错误,包括运行时错误和显式地在应用程序中抛出的错误。 – powerboy 2012-07-15 20:22:41

0

下面的代码在app.js

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

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

相关代码我猜测,错误的是没有被抓住。您是否使用Express错误处理程序?喜欢的东西:

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

更多错误快递处理:http://expressjs.com/guide.html#error-handling

+0

'app.error'已弃用。改用'app.use'。无论如何,两者都不适合我的情况。这可能与mongodb驱动程序有关。 – powerboy 2012-07-15 19:43:50

0

在检查错误关闭mongodb的,使用“!错误”成功的条件,而不是“结果!”的错误。

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

至于定制404,我还没有做,在节点和表达,但我想它会涉及“app.router”。

+0

我试过了。实际上,如果mongodb cound没有找到记录,'result'变成'null',而'err'没有被设置。 – powerboy 2012-07-15 19:52:20

+0

奇怪。我只是用我的应用程序试过 - 它给我带来了一个不存在的记录的错误,但是mongodb和express都继续运行。我没有处理,所以它给了我一个500页的堆栈跟踪。 – Michal 2012-07-15 19:58:00