节点console.log:什么是" stack:[Getter]"?

时间:2015-06-03 15:05:12

标签: node.js console.log

我有来自soap客户端库的回复,当我console.log时,我得到"实际的错误消息&#34 ;;所以我认为它可能是一个字符串。但是,当我使用util.inspect进行记录时,它会向我显示它实际上是一个对象,更具体地说是:

{ [Error: The actual error message] stack: [Getter] }

我到底在这里到底是什么,以及如何处理它(获取纯文本信息)?我之前从未见过它,它显然不是我认为的字符串,但它看起来也不像我曾经习惯的对象。

编辑:我现在只想传递错误的message属性,但由于某种原因这是不可能的:我只能在catch内访问它块。

这是我返回错误的地方:

// Please note that I've just converted this code from coffeescript
// (and changed it a bit) and most stuff is missing (client is actually defined for example).. 
// But the relevant code to understand what's going on is still in here

Shipping.book = function (information, callback) {
  client.BookQuote(information, function (err, res) {

    var processingError = res.BookQuoteResult.ProcessingError;
    var orderLogString = res.BookQuoteResult.OrderLog.string;

    if (!!processingError && !!orderLogString)
      console.log(orderLogString[0].message) // Doesn't log anything
      callback(orderLogString[0])
  }
}

Shipping.bookSync = function (information) {
  var book;
  book = Meteor.wrapAsync(Shipping.book);
  return book(information);
};

这就是我所说的功能:

var err;

try {
  return Shipping.bookSync(information);
} catch (_error) {
  err = _error;
  console.log(err.message); # Logs the plain text error message
}

// ---
// generated by coffee-script 1.9.2

2 个答案:

答案 0 :(得分:1)

stack个实例的Error属性是getter,因为堆栈跟踪的生成并不便宜。因此,通过使其成为一个getter,它只在需要/请求时才会懒惰地创建堆栈跟踪。 util.inspect()仅检查属性,它不会激活getter / functions /其他特殊类型。

如果您只想从Error实例获取消息,可以使用error.message获取文本部分。

最后,您始终可以使用typeof foo === 'string'检查变量的类型,或通过Error明确检查foo instanceof Error

答案 1 :(得分:1)

这是一个对象,它有一个节点不期望的额外属性:

╭« cdrost@xanadu:~ »                                                                                           
╰→ node
> function id(x) { return x; }
undefined
> id.stuff = [1,2,3]
[ 1, 2, 3 ]
> id
{ [Function: id] stuff: [ 1, 2, 3 ] }

因此,您正在使用的库正在向您发送一个Error对象(即由某个function Error(...){...}表达式构造的对象),该对象具有名为{{1的额外意外属性这是stack个对象的列表(由Getter - 命名函数构造)。在这种情况下,列表看起来只有一个Getter

修改:将邮件从Getter块中导出,只需存储邮件即可。由于JS的一些属性有点技术性,这是一个棘手的问题。例如,catch块根据规范提供了新的词汇环境,但您只能将其用于错误参数,因为任何catch语句都会被提升到最接近功能范围,位于var块之外。

您在设置catch时所做的事情确实会从err = _error块中获取错误。但是,JavaScript允许您catch只是任何,包括抛出一个仍然有外部引用的对象:

throw

要解决此问题,请不要存储function trickyError(msg) { var err = new Error(msg) setTimeout(function () { delete err.message; }, 1); throw err; } function example() { try { trickyError("Something insane happened."); } catch (e) { // This logs the message properly because JS is single-threaded: console.log(e.message); // This usually logs `undefined`, but could maybe in some high-load // circumstances log the message properly, if the OS neglects the Node // thread for 100ms and the Node setTimeout scheduler doesn't respect // their temporal order when handling the two events -- I'm not sure // that any standards say that they have to happen in order. setTimeout(function () { console.log(e.message); }, 100); } } ,而是err = _error。由于JS字符串是不可变的,因此其他一些代码可能引用错误消息并不重要。