定義錯誤處理中間件和定義其餘中間件同樣,除了須要 4 個參數,而不是 3 個,其格式以下 (err, req, res, next)
。例如:javascript
app.use(function(err, req, res, next) { console.error(err.stack); res.status(500).send('Something broke!'); });
在其餘 app.use()
和路由調用後,最後定義錯誤處理中間件,好比:java
var bodyParser = require('body-parser'); var methodOverride = require('method-override'); app.use(bodyParser()); app.use(methodOverride()); app.use(function(err, req, res, next) { // 業務邏輯 });
中間件返回的響應是隨意的,能夠響應一個 HTML 錯誤頁面、一句簡單的話、一個 JSON 字符串,或者其餘任何您想要的東西。json
爲了便於組織(更高級的框架),您可能會像定義常規中間件同樣,定義多個錯誤處理中間件。好比您想爲使用 XHR 的請求定義一個,還想爲沒有使用的定義一個,那麼:app
var bodyParser = require('body-parser'); var methodOverride = require('method-override'); app.use(bodyParser()); app.use(methodOverride()); app.use(logErrors); app.use(clientErrorHandler); app.use(errorHandler);
logErrors
將請求和錯誤信息寫入標準錯誤輸出、日誌或相似服務:框架
function logErrors(err, req, res, next) { console.error(err.stack); next(err); }
clientErrorHandler
的定義以下(注意這裏將錯誤直接傳給了 next
):ide
function clientErrorHandler(err, req, res, next) { if (req.xhr) { res.status(500).send({ error: 'Something blew up!' }); } else { next(err); } }
errorHandler
能捕獲全部錯誤,其定義以下:函數
function errorHandler(err, req, res, next) { res.status(500); res.render('error', { error: err }); }
若是向 next()
傳入參數(除了 ‘route’ 字符串),Express 會認爲當前請求有錯誤的輸出,所以跳事後續其餘非錯誤處理和路由/中間件函數。若是需作特殊處理,須要建立新的錯誤處理路由,以下節所示。ui
若是路由句柄有多個回調函數,可以使用 ‘route’ 參數跳到下一個路由句柄。好比:spa
app.get('/a_route_behind_paywall', function checkIfPaidSubscriber(req, res, next) { if(!req.user.hasPaid) { // 繼續處理該請求 next('route'); } }, function getPaidContent(req, res, next) { PaidContent.find(function(err, doc) { if(err) return next(err); res.json(doc); }); });
在這個例子中,句柄 getPaidContent
會被跳過,但 app
中爲 /a_route_behind_paywall
定義的其餘句柄則會繼續執行。日誌
next()
和 next(err)
相似於 Promise.resolve()
和 Promise.reject()
。它們讓您能夠向 Express 發信號,告訴它當前句柄執行結束而且處於什麼狀態。next(err)
會跳事後續句柄,除了那些用來處理錯誤的句柄。
Express 內置了一個錯誤處理句柄,它能夠捕獲應用中可能出現的任意錯誤。這個缺省的錯誤處理中間件將被添加到中間件堆棧的底部。
若是你向 next()
傳遞了一個 error ,而你並無在錯誤處理句柄中處理這個 error,Express 內置的缺省錯誤處理句柄就是最後兜底的。最後錯誤將被連同堆棧追蹤信息一同反饋到客戶端。堆棧追蹤信息並不會在生產環境中反饋到客戶端。
設置環境變量 NODE_ENV
爲 「production」 就可讓應用運行在生產環境模式下。
若是你已經開始向 response 輸出數據了,這時才調用 next()
並傳遞了一個 error,好比你在將向客戶端輸出數據流時遇到一個錯誤,Express 內置的缺省錯誤處理句柄將幫你關閉鏈接並告知 request 請求失敗。
所以,當你添加了一個自定義的錯誤處理句柄後,若是已經向客戶端發送包頭信息了,你還能夠將錯誤處理交給 Express 內置的錯誤處理機制。
function errorHandler(err, req, res, next) { if (res.headersSent) { return next(err); } res.status(500); res.render('error', { error: err });