Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/405.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript NodeJS错误与promise.catch和console.log?_Javascript_Node.js_Promise_Console.log - Fatal编程技术网

Javascript NodeJS错误与promise.catch和console.log?

Javascript NodeJS错误与promise.catch和console.log?,javascript,node.js,promise,console.log,Javascript,Node.js,Promise,Console.log,运行以下代码时,根据是否注释掉了console.log(“fnError:,fnError),我会得到不同的结果。我觉得这很不对劲 调用console.log会如何影响我的承诺? 函数运行(){ var fn=函数(){ 抛出新错误(“错误消息”); }; //返回一个应以失败告终的承诺 //错误对象,其.message为“correct message” var promisifiedFn=函数(){ 返回承诺。解决() .然后(fn) .catch((fnError)=>{ //评论这个可以

运行以下代码时,根据是否注释掉了
console.log(“fnError:,fnError)
,我会得到不同的结果。我觉得这很不对劲

调用
console.log
会如何影响我的承诺?

函数运行(){
var fn=函数(){
抛出新错误(“错误消息”);
};
//返回一个应以失败告终的承诺
//错误对象,其.message为“correct message”
var promisifiedFn=函数(){
返回承诺。解决()
.然后(fn)
.catch((fnError)=>{
//评论这个可以解决问题//
log(“fnError:,fnError”);
///////////////////////////////////////
fnError.message=“正确消息”;
抛出错误;
})
}
promisifiedFn().catch((e)=>{
日志(“捕获错误。消息:”,e.message);
日志(“捕获的错误:”,e);
});
}
run();
上述结果产生:

// fnError:  Error: incorrect message
//     at fn (/Users/sam/dev/ethereum/pennyeth/js/temp.js:18:9)
//     at <anonymous>
//     at process._tickCallback (internal/process/next_tick.js:169:7)
//     ...
// caught error.message: correct message
// caught error: Error: incorrect message
//     at fn (/Users/sam/dev/ethereum/pennyeth/js/temp.js:18:9)
//     at <anonymous>
//     at process._tickCallback (internal/process/next_tick.js:169:7)
//     ...

运行node 8.0.0时,我能够用下面4行代码重现这个“bug”

var e = new Error('first');
console.log(e);
e.message = 'new';
console.log(e);
我试过Chrome 59,但没有同样的问题

但是,节点7.9.0、节点8.0.0和节点8.1.2都存在此问题

我在GitHub上报告了一个bug,所以我们将看到它的结果

更新1:为了表明这不是时间问题,我们可以添加
setTimeout
调用

var e = new Error('first');
console.log(e);
setTimeout(() => { e.message = 'new'; }, 1000);
setTimeout(() => console.log(e), 2000);
即使我们等待调用
console.log()
,问题仍然存在,这让我相信输出是缓存的

更新2:我从GitHub上的mscdex得到了一个响应:

这是预期的,因为您看到的是堆栈跟踪,其中包括生成错误消息后的错误消息。堆栈跟踪是延迟生成的,并且只生成一次(出于性能原因),因此您可以看到两次相同的输出

但是,如果您将代码更改为输出e.message,您将在输出中看到预期的更改

最终,mscdex和Bergi都认为根本原因是评估懒惰


您所做的可能不是常见的情况,因此我将避免在将来这样做,因为node.js团队似乎不会改变这种行为。

这是预期的行为

记录错误(至少通过
util.inspect
String
检查)会评估其
.stack
属性。实例化错误对象时不会初始化堆栈字符串,而是延迟构建以节省内存。堆栈跟踪将包括错误消息,当您更改
.message
属性时,它将反映在堆栈跟踪中,具体取决于是否已创建该属性

发件人:

为了提高效率,在捕获堆栈跟踪时不会对其进行格式化,而是在第一次访问堆栈属性时按需进行格式化

和来自:

当访问error.stack属性时,表示堆栈跟踪的字符串将延迟生成


注意:在我的实际应用程序代码中,在重新引用错误之前,我没有记录错误,并且我仍然得到这种行为。不幸的是,我无法找到一个最简单的例子。这很奇怪。我试过Chrome 59,但没有同样的问题。但是节点7.9.0、节点8.0.0和节点8.1.2都有这种行为(或bug)。我唯一的想法是console.log在转换到标准输出之前缓存错误对象。请注意,两个“不正确的消息”结果都记录了同一个对象。我的应用程序代码仍然存在问题,我甚至没有执行
console.log
,仍然得到错误的错误对象。我抛出了一个新错误,但它丢失了原始堆栈跟踪。可以执行
控制台.log(Object.getOwnPropertyDescriptor(fnError,“message”)
吗?我的应用程序代码中仍然存在这个问题,它执行类似的操作,但不执行
控制台.log
,这意味着我得到了“旧的”错误消息。为什么Chrome的行为与Node.js不同?node是否正在进行此优化而chrome没有?@styfle我还没有尝试过,但我怀疑区别只是在
控制台中。log
而不是
错误。stack
@styfle我可以在chrome中显式访问
.stack
时重现它。但是事实上,
console.log(e)
本身确实显示了更新的消息。这实际上让我怀念Java。。此外,您还可以将异常链接在一起,永远不会出现这种混乱。@Bergi是否还有其他事件导致生成
堆栈
?即使不执行
console.log
,我也会得到相同的行为,尽管我还不能将其简化为一个示例。
var e = new Error('first');
console.log(e);
setTimeout(() => { e.message = 'new'; }, 1000);
setTimeout(() => console.log(e), 2000);