Rumah  >  Artikel  >  hujung hadapan web  >  Analisis ringkas tentang ralat pengendalian middleware Express dalam Node

Analisis ringkas tentang ralat pengendalian middleware Express dalam Node

青灯夜游
青灯夜游ke hadapan
2022-04-06 20:02:303147semak imbas

Artikel ini akan membawa anda melalui ralat pengendalian middleware Express dalam Node, dan memperkenalkan kaedah untuk mentakrifkan ralat pengendalian middleware dan menggunakannya dengan async/menunggu saya harap ia akan membantu anda.

Analisis ringkas tentang ralat pengendalian middleware Express dalam Node

Ralat pengendalian middleware Express membantu anda mengendalikan ralat tanpa perlu mengulangi kerja yang sama. Dengan mengandaikan anda mengendalikan ralat secara langsung dalam pengendali laluan Ekspres:

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

Kod di atas akan berfungsi dengan baik, bagaimanapun, bagaimana jika terdapat ratusan antara muka, maka logik pengendalian ralat akan menjadi tidak dapat dikekalkan kerana ia diulang ratusan kali.

Tentukan perisian tengah pengendalian ralat

Express dibahagikan kepada jenis yang berbeza mengikut bilangan parameter yang digunakan oleh fungsi perisian tengah. Fungsi middleware yang menerima 4 parameter ditakrifkan sebagai Ralat mengendalikan middleware dan hanya akan dipanggil apabila ralat berlaku.

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 akan mengendalikan ralat penyegerakan untuk anda secara automatik, seperti yang ditunjukkan dalam kaedah routeHandler() di atas. Tetapi Express tidak mengendalikan ralat tak segerak. Jika ralat tak segerak berlaku, next() perlu dipanggil.

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

Ingat bahawa perisian tengah Express dilaksanakan secara berurutan. Anda harus menentukan pengendali ralat terakhir, selepas semua perisian tengah yang lain. Jika tidak, pengendali ralat anda tidak akan dipanggil:

digunakan dengan async/await

Express tidak dapat menangkap pengecualian promise, Express telah ditulis sebelum ES6, tidak ada idea bagaimana untuk mengendalikan async/await Ia tidak memberikan penyelesaian yang baik.

Sebagai contoh, pelayan berikut tidak akan berjaya menghantar respons HTTP kerana Janji reject tidak akan pernah dikendalikan:

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)

Kami boleh membungkus ini atau menggunakan perpustakaan sedia ada untuk melakukan ia menangkap.

Pertama, kami hanya merangkum fungsi untuk menyambung async/await dengan perisian tengah pengendalian ralat Express.

Nota : Fungsi Async mengembalikan Promise, jadi anda perlu memastikan catch() semua ralat dan hantarkannya kepada 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')
}))

Gunakan pustaka pihak ketiga express-async-errors, hack sokongan async/menunggu ES6 mudah:

require('express-async-errors')
app.get('*', async (req, res, next) => {
  await new Promise((resolve) => setTimeout(() => resolve(), 50))
  throw new Error('woops')
})

Akhir sekali

perisian tengah pengendalian ralat nyata membolehkan anda mengendalikan ralat dengan cara yang memaksimumkan pengasingan kebimbangan. Anda tidak perlu menangani ralat dalam logik perniagaan anda, malah async/await jika anda menggunakan try/catch. Ralat ini akan muncul dalam pengendali ralat anda, yang kemudiannya boleh memutuskan cara untuk membalas permintaan tersebut. Pastikan anda memanfaatkan ciri hebat ini dalam apl Express anda yang seterusnya!

Untuk lebih banyak pengetahuan berkaitan nod, sila lawati: tutorial nodejs!

Atas ialah kandungan terperinci Analisis ringkas tentang ralat pengendalian middleware Express dalam Node. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam