我问了另一个与错误有关的问题。不知道我是否应该编辑该问题。

无论如何,对于以下代码:

app.use((err, req, res, next) => {
  res.status(err.status || 500);
  res.json({
    message: err.message,
    err // this err object doens't have err.message property
  });
  next();
});


我不知道这是Node还是Express。

有人可以解释这种情况的发生方式和原因吗?

返回时err对象是否不应该包含其所有属性?

目前,我正在这样做以解决此问题:

res.json({
  err: Object.assign(err, { message: err.message })
});

最佳答案

返回时err对象是否不应该包含其所有属性?


对于大多数JSON序列化程序,这将完全取决于属性是否可枚举。

在规范中,Error对象的message属性is defined as non-enumerable,因此它不会显示在JSON中。

听到您的assign方法有效的消息,我感到很惊讶,因为根据规范,它应该只写回现有属性,该属性是不可枚举的,并且将保持不变。这就是V8在Chrome 50中的功能:



var err = new Error("the error");
console.log("err.message is enumerable? " + getPropDesc(err, "message").enumerable);
var obj = Object.assign(err, {message: "updated"});
console.log("obj === err? " + (obj === err)); // should be true
console.log("obj.message is enumerable? " + getPropDesc(obj, "message").enumerable);
console.log("JSON for err: " + JSON.stringify(err));
if (obj !== err) { // shouldn't be true
  console.log("JSON for obj: " + JSON.stringify(obj));
}

function getPropDesc(o, prop) {
  var desc;
  while (o) {
    desc = Object.getOwnPropertyDescriptor(o, prop);
    if (desc) {
      return desc;
    }
    o = Object.getPrototypeOf(o);
  }
  return null;
}





我希望这可以工作:

res.json({
  err: Object.assign({}, err, { message: err.message })
  // Note -----------^^^^
});


...但不是您引用的内容。也许您获得的err对象不是Error实例。 (在ES5和更早版本中)Error非常难以子类化,因此很可能是您正在使用的代码没有尝试执行,而是这样做:

var err = Object.create(new Error("the error"));


这将导致您看到的行为:



var err = Object.create(new Error("the error"));
console.log("err.message is enumerable? " + getPropDesc(err, "message").enumerable);
var obj = Object.assign(err, {message: "updated"});
console.log("obj === err? " + (obj === err)); // should be true
console.log("obj.message is enumerable? " + getPropDesc(obj, "message").enumerable);
console.log("JSON for err: " + JSON.stringify(err));
if (obj !== err) { // shouldn't be true
  console.log("JSON for obj: " + JSON.stringify(obj));
}

function getPropDesc(o, prop) {
  var desc;
  while (o) {
    desc = Object.getOwnPropertyDescriptor(o, prop);
    if (desc) {
      return desc;
    }
    o = Object.getPrototypeOf(o);
  }
  return null;
}

关于javascript - 返回的快速err对象不包含err.message,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37347619/

10-12 17:57