传播运算符似乎没有复制完整的对象

spread operator does not seem to copy full object

我正在尝试实现快速错误处理中间件。它正在工作,但我不明白为什么我必须在将 err 复制到 error 后将 error.message 设置为等于 err.message。扩展运算符是否没有复制 err 中的所有属性?当我检查 err 对象时,我什至没有看到消息或堆栈属性。另外,为什么它能够在 if 块中创建错误消息之前记录错误消息。

这就是我扩展错误的方式

// src/utils/errorResponse.js

class ErrorResponse extends Error {
  constructor(message, statusCode) {
    super(message)
    this.statusCode = statusCode
  }
}
module.exports = ErrorResponse

自定义错误处理程序中间件

// src/middleware/error.js

const ErrorResponse = require('../utils/errorResponse')

const errorHandler = (err, req, res, next) => {
  let error = { ...err } 
  console.log({ error.message }) // undefined
  error.message = err.message
  console.log({ error.message }) // `Resource not found with id of ${err.value}`

  // Log to console for dev
  // console.log(error.stack)

  // Mongoose bad ObjectId
  if (err.name === 'CastError') {
    const message = `Resource not found with id of ${err.value}`
    error = new ErrorResponse(message, 404)
  } else {
    console.log(error.name)
  }

  res.status(error.statusCode || 500).json({
    success: false,
    error: error.message || 'Server Error',
  })
}

module.exports = errorHandler

我通过使用错误的 ObjectID 发出获取请求来触发错误

// src/controllers/bootcamp.js

const Bootcamp = require('../models/Bootcamp')

...

// @desc Get single bootcamp
// @route GET /api/v1/bootcamps/:id
// @access Public
exports.getBootcamp = async (req, res, next) => {
  try {
    const bootcamp = await Bootcamp.findById(req.params.id)
    if (!bootcamp) {
      return next(err)
    }
    res.status(200).json({ success: true, data: bootcamp })
  } catch (err) {
    next(err)
  }
}

发生这种情况是因为您获取的 err 参数是错误类型对象,消息键存在于错误对象的原型中,并且传播运算符浅拷贝对象键(不包括原型键)

来自 mdn 的传播运算符声明 -

ECMAScript 提案 (ES2018) 的 Rest/Spread 属性向对象文字添加了扩展属性。它将自己的可枚举属性从提供的对象复制到新对象。

Shallow-cloning (excluding prototype) 或现在可以使用比 Object.assign().

更短的语法来合并对象

供参考-

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax