Express 中的中央错误处理

2025-05-25

Express 中的中央错误处理

Express 是一个快速、无偏见、极简的 Node.js Web 框架 -文档

无论是使用 Express 还是其他任何语言构建应用程序,错误处理都是不可缺少的例行工作。

使用 Express 或其他框架/库构建 API 端点时,每个用例都需要进行验证检查,并且始终需要向用户返回错误响应。处理这些错误并为每个验证返回响应会变得非常繁琐,并使代码库变得混乱。
让我们考虑以下示例:

const validateUser = async (req, res, next) => {
  try {
    const { email, password } = req.body
    if (!email || !password) {
      return res.status(400).json({
        status: 'error',
        message: 'Missing required email and password fields',
      })
    }
    const user = await db.User.findOne({ where: { email }});
    if (!user) {
      return res.status(404).json({
        status: 'error',
        message: 'User with the specified email does not exists',
      })
    }
    next()
  } catch (error) {
    return res.status(500).json({
      status: 'error',
      message: 'An error occurred trying to process your request',
    })
  }
}
Enter fullscreen mode Exit fullscreen mode

看看上面的代码片段,你肯定会同意我的观点:每个检查点都返回错误响应,这看起来已经很乱了。如果你的代码库里只有这些代码,那还好,但当你需要在代码库中的多个方法或函数中重复相同的方法时,问题就出现了。

在我们深入寻找解决方案来改进上面的代码片段之前,让我们先看看这篇文章需要什么:

要求

  • NodeJs已安装
  • 已安装 npm 或 yarn
  • 了解 Nodejs/Express

注意:本文假设读者已具备 NodeJs/Express 的基础知识。因此,部分细节可能会被跳过。

为了继续,请在此处克隆本文使用的存储库。

步骤 1.创建自定义 **Error * 构造函数*
我们需要创建一个自定义 Error 构造函数来扩展JavaScript Error 构造函数

在你之前克隆的项目中,创建一个名为helpers 的目录。在helpers目录中,创建一个名为error.js的文件。

将下面的代码片段添加到error.js中

class ErrorHandler extends Error {
  constructor(statusCode, message) {
    super();
    this.statusCode = statusCode;
    this.message = message;
  }
}
module.exports = {
  ErrorHandler
}
Enter fullscreen mode Exit fullscreen mode

请注意,我们导出了 ErrorHandler,以便我们可以从index.js文件导入它。

接下来,我们需要创建一个函数来向用户返回格式化的错误响应。

将下面的代码片段添加到error.js文件中。

const handleError = (err, res) => {
  const { statusCode, message } = err;
  res.status(statusCode).json({
    status: "error",
    statusCode,
    message
  });
};
Enter fullscreen mode Exit fullscreen mode

更新module.exports块以包含handleError如下所示的函数:

module.exports = {
  ErrorHandler,
  handleError
}
Enter fullscreen mode Exit fullscreen mode

步骤 2.创建错误处理中间件

中间件函数是指可以访问请求对象 (req)、响应对象 (res) 以及应用程序请求-响应周期中的下一个中间件函数的函数。
下一个中间件函数通常用名为 next 的变量表示。Express文档

错误处理中间件是一种特殊类型的中间件,与常规中间件不同,它接受四个参数。第一个参数是错误对象。
以下代码片段展示了一个错误处理中间件的示例:

function(err, req, res, next) {
  //code goes here
}
Enter fullscreen mode Exit fullscreen mode

在 中index.js,我们来添加一个错误处理中间件,在此之前,我们先导入handleError里面的函数index.js

index.js文件应如下所示:

const express = require('express')
const { handleError } = require('./helpers/error')
const app = express()

app.use(express.json())
const PORT = process.env.PORT || 3000

app.get('/', (req, res) => {
  return res.status(200).json('Hello world'); 
})

app.use((err, req, res, next) => {
  handleError(err, res);
});
app.listen(PORT, () => console.log(`server listening at port ${PORT}`))
Enter fullscreen mode Exit fullscreen mode

注意我们如何调用handleError函数并将错误对象和响应对象传递给它。

注意:错误处理中间件必须是其他中间件和路由中的最后一个,才能正常运行。

现在,在应用程序中任何需要检查错误的地方,只需抛出ErrorHandler构造函数即可。
现在我们可以应用错误处理机制来重构之前混乱的代码。它应该如下所示:

const validateUser = async (req, res, next) => {
  try {
    const { email, password } = req.body
    if (!email || !password) {
      throw new ErrorHandler(404, 'Missing required email and password fields')
    }
    const user = await  db.User.findOne({ where: { email }});
    if (!user) {
      throw new ErrorHandler(404, 'User with the specified email does not exists')
    }
    next()
  } catch (error) {
    next(error)
  }
}
Enter fullscreen mode Exit fullscreen mode

注意我们是如何将错误传递给next上面的函数的。它的作用只是将错误传递给我们在 中定义的错误处理中间件index.js

让我们添加一条路由来测试我们刚刚创建的错误处理机制。添加index.js以下代码片段:

app.get('/error', (req, res) => {
  throw new ErrorHandler(500, 'Internal server error');
})
Enter fullscreen mode Exit fullscreen mode

记得在 中导入 ErrorHandler index.js。它应该如下所示:

const { handleError, ErrorHandler } = require('./helpers/error')
Enter fullscreen mode Exit fullscreen mode

运行 npm start 启动服务器,然后访问路由/error。您将收到类似如下所示的响应:

{
    "status": "error",
    "statusCode": 500,
    "message": "Internal server error"
}
Enter fullscreen mode Exit fullscreen mode

结论

在本文中,我们确定了 Express 应用程序中需要有一个中央错误处理程序。我们还演示了实现中央错误处理程序所需的步骤。

如果您有任何问题或意见,希望本文能够改进,请通过Twitter联系我
感谢您的阅读。✌️

文章来源:https://dev.to/nedsoft/central-error-handling-in-express-3aej
PREV
Supertest Jest 使用 Jest 和 Supertest 测试 NodeJs/Express API
NEXT
使用 NextAuth.js 立即向现有的无服务器 Next.js 应用程序添加身份验证!