运行以下代码时,根据是否将console.log("fnError: ", fnError)注释掉,我得到不同的结果。这对我来说似乎很不对劲。

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

function run() {
    var fn = function(){
        throw new Error("incorrect message");
    };

    // returns a promise that should fail with
    // an error object whose .message is "correct message"
    var promisifiedFn = function(){
        return Promise.resolve()
            .then(fn)
            .catch((fnError) => {
                // commenting this out fixes things! //
                console.log("fnError: ", fnError);
                ///////////////////////////////////////

                fnError.message = "correct message";
                throw fnError;
            })
    }

    promisifiedFn().catch((e) => {
        console.log("caught error.message:", e.message);
        console.log("caught error:", 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)
//     ...

请注意正在记录“不正确的消息”。如果您将console.log("fnError: ", fnError)注释掉,则会得到以下信息:
// caught error.message: correct message
// caught error: Error: correct 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

最佳答案

这是预期的行为。

记录错误(至少通过util.inspectString进行记录)会评估其.stack属性。实例化错误对象时,不会初始化堆栈字符串,但是会延迟构建堆栈字符串以节省内存。堆栈跟踪将包含错误的消息,并且当您更改.message属性时,取决于是否已创建,它将在堆栈跟踪中反射(reflect)或不反射(reflect)。

the V8 stack trace API description:



并从the official node Error documentation:

09-16 21:04