2012-07-15 62 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