Analisis ringkas tentang ralat pengendalian middleware Express dalam Node

青灯夜游
Lepaskan: 2022-04-07 20:49:30
ke hadapan
3133 orang telah melayarinya

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 })
})
Salin selepas log masuk

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 })
})
Salin selepas log masuk

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
  })
})
Salin selepas log masuk

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)
Salin selepas log masuk

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')
}))
Salin selepas log masuk

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')
})
Salin selepas log masuk

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!

Label berkaitan:
sumber:juejin.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!