
如何快速入門VUE3.0:進入學習
Express 的錯誤處理中介軟體可協助您處理錯誤,而無需重複相同的工作。假設您直接在Express 路由處理程序中處理錯誤:
app.put('/user/:id', async (req, res) => {
let user
try {
user = await User.findOneAndUpdate({ _id: req.params.id }, req.body)
} catch (err) {
return res.status(err.status || 500).json({ message: err.message })
}
return res.json({ user })
})上面的程式碼可以正常運作,但是,如果有數百個介面呢,那麼錯誤處理邏輯將變得不可維護,因為它被重複了數百次。
Express 根據中介軟體函數所採用的參數數量分為不同的型別。接受4 個參數的中間件函數被定義為錯誤處理中間件,只有在發生錯誤時才會被呼叫。
const app = require('express')()
app.get('*', function routeHandler() {
// 此中間件拋出一個錯誤,Express 會直接轉到下一個錯誤處理程序throw new Error('Oops!')
})
app.get('*', (req, res, next) => {
// 此中間件不是錯誤處理程序(只有3個參數),Express 將跳過它,因為先前的中間件中存在錯誤console.log('這裡不會列印')
})
// 您的函數必須接受4 個參數,以便Express 將其視為錯誤處理中間件。
app.use((err, req, res, next) => {
res.status(500).json({ message: err.message })
}) Express 會自動為您處理同步錯誤,如上面的routeHandler()方法。但是Express 不處理非同步錯誤。如果出現非同步錯誤,則需要呼叫next() 。
const app = require('express')()
app.get('*', (req, res, next) => {
// next() 方法告訴Express 要轉到鏈中的下一個中間件。
// Express 不處理非同步錯誤,因此您需要透過呼叫next() 來報告錯誤。
setImmediate(() => {
next(new Error('Oops'))
})
})
app.use((err, req, res, next) => {
res.status(500).json({
message: err.message
})
})請記住,Express 中間件是依序執行的。您應該在所有其他中間件之後,最後定義錯誤處理程序。否則,您的錯誤處理程序將不會被呼叫:
async/await一起使用Express 無法捕獲promise的異常,Express 在ES6 之前編寫,對於如何處理async/await它扔沒有好的解決方案。
例如,下面的伺服器永遠不會成功發送HTTP 回應,因為Promise reject永遠不會被處理:
const app = require('express')()
app.get('*', (req, res, next) => {
// 回報非同步錯誤必須經過next()
return new Promise((resolve, reject) => {
setImmediate(() => reject(new Error('woops')))
}).catch(next)
})
app.use((error, req, res, next) => {
console.log('will not print')
res.json({ message: error.message })
})
app.listen(3000)我們可以封裝或使用現有的函式庫來進行擷取。
首先,我們先簡單封裝一個函數,將async/await與Express 錯誤處理中間件連結起來。
注意:非同步函數會傳回Promise,因此您需要確保
catch()所有錯誤並將其傳遞給next()。
function wrapAsync(fn) {
return function(req, res, next) {
fn(req, res, next).catch(next)
}
}
app.get('*', wrapAsync(async (req, res) => {
await new Promise(resolve => setTimeout(() => resolve(), 50))
// Async error!
throw new Error('woops')
}))使用第三方函式庫express-async-errors ,一個簡單的ES6 async/await 支援hack:
require('express-async-errors')
app.get('*', async (req, res, next) => {
await new Promise((resolve) => setTimeout(() => resolve(), 50))
throw new Error('woops')
})Express 錯誤處理中間件可讓您以最大化關注點分離的方式處理錯誤。您不需要處理業務邏輯中的錯誤,如果使用async/await ,甚至不需要try/catch 。這些錯誤將出現在您的錯誤處理程序中,然後您的錯誤處理程序可以決定如何回應請求。確保在下一個Express 應用程式中充分利用這項強大功能!