express中的錯誤處理


錯誤處理

定義錯誤處理中間件和定義其他中間件一樣,除了需要 4 個參數,而不是 3 個,其格式如下 (err, req, res, next)。例如:

app.use(function(err, req, res, next) { console.error(err.stack); res.status(500).send('Something broke!'); }); 

在其他 app.use() 和路由調用后,最后定義錯誤處理中間件,比如:

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 字符串,或者其他任何您想要的東西。

為了便於組織(更高級的框架),您可能會像定義常規中間件一樣,定義多個錯誤處理中間件。比如您想為使用 XHR 的請求定義一個,還想為沒有使用的定義一個,那么:

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):

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 會認為當前請求有錯誤的輸出,因此跳過后續其他非錯誤處理和路由/中間件函數。如果需做特殊處理,需要創建新的錯誤處理路由,如下節所示。

如果路由句柄有多個回調函數,可使用 ‘route’ 參數跳到下一個路由句柄。比如:

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM