Home > Web Front-end > JS Tutorial > A brief analysis of the error handling middleware of Express in Node

A brief analysis of the error handling middleware of Express in Node

青灯夜游
Release: 2022-04-07 20:49:30
forward
3235 people have browsed it

This article will take you to understand the error handling middleware of Express in Node, and introduce the method of defining error handling middleware and using it with async/await. I hope it will be helpful to everyone!

A brief analysis of the error handling middleware of Express in Node

Express's error handling middleware helps you handle errors without repeating the same work. Assuming you handle errors directly in Express route handler:

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 })
})
Copy after login

The above code will work fine, however, what if there are hundreds of interfaces, then the error handling logic will become unmaintainable because it is repeated Hundreds of times.

Define error handling middleware

Express is divided into different types according to the number of parameters used by the middleware function. The middleware function that accepts 4 parameters is defined as Error handling middleware and will only be called when an error occurs.

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 })
})
Copy after login

Express will automatically handle synchronization errors for you, such as the routeHandler() method above. But Express doesn't handle asynchronous errors. If an asynchronous error occurs, next() needs to be called.

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
  })
})
Copy after login

Remember that Express middleware is executed sequentially. You should define error handlers last, after all other middleware. Otherwise, your error handler will not be called:

Used with async/await

Express cannot catch exceptions for promise, Express was written before ES6 and there was no good solution for how to handle async/await it threw.

For example, the following server will never successfully send the HTTP response because the Promise reject will never be processed:

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)
Copy after login

We can wrap or use an existing library to capture.

First, we simply encapsulate a function to connect async/await with Express error handling middleware.

Note: Async functions return Promise, so you need to make sure to catch() all errors and pass them to 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')
}))
Copy after login

Using third-party librariesexpress-async-errors, a simple ES6 async/await support hack:

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

Finally

Express error handling middleware allows you to handle errors in a way that maximizes separation of concerns. You don't need to handle errors in your business logic, or even try/catch if you use async/await. These errors will appear in your error handler, which can then decide how to respond to the request. Make sure to take advantage of this powerful feature in your next Express app!

For more node-related knowledge, please visit: nodejs tutorial!

The above is the detailed content of A brief analysis of the error handling middleware of Express in Node. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:juejin.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template