首頁 > web前端 > js教程 > 主體

淺析Node中Express的錯誤處理中介軟體

青灯夜游
發布: 2022-04-07 20:49:30
轉載
3175 人瀏覽過

這篇文章帶大家了解一下Node中Express的錯誤處理中間件,介紹一下定義錯誤處理中間件、與 async/await 一起使用的方法,希望對大家有所幫助!

淺析Node中Express的錯誤處理中介軟體

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 應用程式中充分利用這項強大功能!

更多node相關知識,請造訪:nodejs 教學

以上是淺析Node中Express的錯誤處理中介軟體的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:juejin.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板