I'm trying to understand how can I get a full stack trace from a promise rejection caused by a setTimeout
我试图了解如何从setTimeout引起的承诺拒绝中获得完整的堆栈跟踪
I'm running the following example:
我正在运行以下示例:
'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();
And I'm getting this output:
而且我得到了这个输出:
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)
How can I make make the stack trace of the promise that is initiated with setTimeout be more verbose like the promise without setTimeout
?
如何使用setTimeout启动的承诺的堆栈跟踪更像是没有setTimeout的promise更详细?
When this happen to me in real production code, I can't know exactly where the error was initiated from. Which makes it very difficult to debug.
当在实际生产代码中发生这种情况时,我无法确切地知道错误的起源。这使得调试非常困难。
2 个解决方案
#1
0
I've done something like the following before:
我之前做过类似的事情:
async function f2() {
return new Promise((resolve, reject) => {
const potentialError = new Error('Error in timeout');
setTimeout(() => {
reject(potentialError);
}, 0);
});
}
That'll result in an error just like the one outside setTimeout
. Wherever you create your error, that'll dictate your stack trace.
这将导致错误,就像setTimeout之外的错误一样。无论您在何处创建错误,都将决定您的堆栈跟踪。
One use case for this for me has been a test that times out because a promise never resolves (in my case, with puppeteer and mocha/jasmine). Because the timeout had no meaningful stack trace, I wrote a wrapper around the promise that includes a setTimeout
, much like this example.
对我来说,一个用例是一个超时的测试,因为承诺永远不会解决(在我的情况下,使用puppeteer和mocha / jasmine)。因为超时没有有意义的堆栈跟踪,所以我写了一个包含setTimeout的promise的包装器,就像这个例子一样。
#2
0
I'd try to write it like this:
我试着这样写:
async function f() {
await new Promise((resolve, reject) => {
setTimeout(resolve, 0);
});
throw new Error('Error after timeout');
}
Try to avoid doing anything in non-promise callbacks.
尽量避免在非承诺回调中做任何事情。
#1
0
I've done something like the following before:
我之前做过类似的事情:
async function f2() {
return new Promise((resolve, reject) => {
const potentialError = new Error('Error in timeout');
setTimeout(() => {
reject(potentialError);
}, 0);
});
}
That'll result in an error just like the one outside setTimeout
. Wherever you create your error, that'll dictate your stack trace.
这将导致错误,就像setTimeout之外的错误一样。无论您在何处创建错误,都将决定您的堆栈跟踪。
One use case for this for me has been a test that times out because a promise never resolves (in my case, with puppeteer and mocha/jasmine). Because the timeout had no meaningful stack trace, I wrote a wrapper around the promise that includes a setTimeout
, much like this example.
对我来说,一个用例是一个超时的测试,因为承诺永远不会解决(在我的情况下,使用puppeteer和mocha / jasmine)。因为超时没有有意义的堆栈跟踪,所以我写了一个包含setTimeout的promise的包装器,就像这个例子一样。
#2
0
I'd try to write it like this:
我试着这样写:
async function f() {
await new Promise((resolve, reject) => {
setTimeout(resolve, 0);
});
throw new Error('Error after timeout');
}
Try to avoid doing anything in non-promise callbacks.
尽量避免在非承诺回调中做任何事情。