如何在带有promise的setTimeout中看到完整的堆栈错误跟踪
我试图了解如何从setTimeout
引起的承诺拒绝获得完整的堆栈跟踪
我正在运行以下示例:
'use strict';
function main() {
f1().catch(e => {
console.error('got error with trace:');
console.error(e);
});
f2().catch(e => {
console.error('got error with trace:');
console.error(e);
});
}
async function f1() {
return new Promise((resolve, reject) => {
reject(new Error('Error in normal flow'));
});
}
async function f2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('Error in timeout'));
}, 0);
});
}
main();
我得到了这个输出:
got error with trace:
Error: Error in normal flow
at Promise (/Users/me/project/example.js:25:12)
at Promise (<anonymous>)
at f2 (/Users/me/project/example.js:24:10)
at main (/Users/me/project/example.js:9:3)
at Object.<anonymous> (/Users/me/project/example.js:29:1)
at Module._compile (module.js:569:30)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3)
got error with trace:
Error: Error in timeout
at Timeout.setTimeout [as _onTimeout] (/Users/me/project/example.js:18:14)
at ontimeout (timers.js:488:11)
at tryOnTimeout (timers.js:323:5)
at Timer.listOnTimeout (timers.js:283:5)
如何使用setTimeout启动的承诺的堆栈跟踪更加冗长,就像没有setTimeout
的承诺一样?
当在实际生产代码中发生这种情况时,我无法确切地知道错误的起源。这使得调试非常困难。
回答如下:我之前做过类似的事情:
async function f2() {
return new Promise((resolve, reject) => {
const potentialError = new Error('Error in timeout');
setTimeout(() => {
reject(potentialError);
}, 0);
});
}
这将导致像setTimeout
之外的错误。无论您在何处创建错误,都会指示您的堆栈跟踪。
对我来说,一个用例是一个超时的测试,因为承诺永远不会解决(在我的情况下,使用puppeteer和mocha / jasmine)。因为超时没有有意义的堆栈跟踪,所以我写了a wrapper around the promise that includes a setTimeout
,就像这个例子。