Express中如何向客户端返回错误消息对象?

kap*_*t12 3 error-handling node.js express server

我有这样的代码块:

router.post('/users/login', async (req, res) => {
  try {
    const { email, password } = req.body
    const user = await User.findByCredentials(email, password)
    console.log(user) //false
    if (!user) {
      throw new Error('Login failed! Check authentication credentials')
    }
    const token = await user.generateAuthToken()
    res.status(200).json({ user, token })
  } catch (err) {
    console.log(err) //Error: Login failed! Check authentication credentials at C:\Users...
    res.status(400).json(err)
  }
})
Run Code Online (Sandbox Code Playgroud)

一切正常,直到没有错误为止。当 Postman 中发生错误时,userfalse只返回空对象{}。也用res.status(400).json({error: err})它给了我{ "err": {} }

我想收到这样的对象{ "error": "Login failed! Check authentication credentials" }

jfr*_*d00 5

错误对象在 JSON 中不能很好地序列化,因为它们的某些属性是不可枚举的,因此JSON.stringify()在使用它时不会包含它们res.json(err)
这就是为什么res.json(err)没有显示您想要的内容。

不包括不可枚举属性的可能原因是它们可能包含堆栈跟踪和其他不打算发送回客户端的信息。JSON.stringify()这只是 Error 对象如何工作和如何实现的副产品,并且res.json()只是继承了这些问题以及两者之间的交互。我从来不明白为什么主要.message属性是不可枚举的,因为这对我来说从来没有意义,但它确实如此。

有多种可能的解决方法:

  1. 您可以添加自己的.json2()方法,其中包括 Error 对象的所有属性(甚至是不可枚举的属性)。
  2. 您可以使用Express 错误处理方案,您可以在其中调用next(err)并提供一个被调用的集中式错误处理程序,并且您可以在那里对错误响应进行自己的序列化。
  3. 您可以创建 Error 的子类来填充将显示在 JSON 中的可枚举属性并使用它。

选项 #3 可能如下所示:

class RouteError extends Error {
    constructor(msg, statusCode = 500) {
        super(msg);
        // define my own enumerable properties so they
        // will show up in JSON automatically
        this.error = msg;
        this.statusCode = statusCode;
    }
}

router.post('/users/login', async (req, res) => {
  try {
    const { email, password } = req.body
    const user = await User.findByCredentials(email, password)
    console.log(user) //false
    if (!user) {
      throw new RouteError('Login failed! Check authentication credentials', 401)
    }
    const token = await user.generateAuthToken()
    res.status(200).json({ user, token })
  } catch (err) {
    console.log(err) //Error: Login failed! Check authentication credentials at C:\Users...
    res.status(err.statusCode).json(err);
  }
});
Run Code Online (Sandbox Code Playgroud)

此示例将生成以下响应:

{"error":"Login failed! Check authentication credentials","statusCode":401}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

4411 次

最近记录:

3 年,1 月 前