在Angular的github问题中搜索“Uncaught(in promise)”,谷歌或这里的stackoverflow会产生很多非常具体的结果,但我的问题有点宽泛(而且由于结果的扩散,我不知道知道这是否重复)
前提:在我的代码的某个地方,我有一个未被捕获的承诺拒绝(Angular 4.4.4)
例:
案例1:简单拒绝
在MyComponent中:
ngOnInit() {
Promise.reject("foo");
}
在控制台中产生这个(很好,我可以看到它来自哪里):
ERROR Error: Uncaught (in promise): foo
at resolvePromise (zone.js:824)
at Function.ZoneAwarePromise.reject (zone.js:903)
at MyComponent.webpackJsonp.../../../../../src/app/component/my.component.ts.MyComponent.ngOnInit (my.component.ts:nn)
案例2:新承诺,抛出错误
在MyComponent中:
ngOnInit() {
new Promise((resolve, reject) => {
throw new Error("foo");
}).then(() => {
console.log("ain't gonna happen");
});
}
在控制台中产生这个(更好的是,当场放弃位置):
ERROR Error: Uncaught (in promise): Error: foo
Error: foo
at my.component.ts:nn
at new ZoneAwarePromise (zone.js:890)
at MyComponent.webpackJsonp.../../../../../src/app/component/my.component.ts.LMyComponent.ngOnInit (my.component.ts:nn)
这也适用于链接,例如以下内容在控制台中或多或少地提供相同的堆栈跟踪。
ngOnInit() {
const promise3 = new Promise((resolve, reject) => {
throw new Error("baz");
});
const promise2 = new Promise((resolve, reject) => {
resolve(promise3);
});
const promise1 = new Promise((resolve, reject) => {
resolve(promise2);
});
promise1.then(p1=> console.log(p1));
}
案例3:使用拒绝(...)
在MyComponent中:
ngOnInit() {
new Promise((resolve, reject) => {
reject("foo");
}).then(() => {
console.log("ain't gonna happen");
});
}
使用promise的reject方法改变抛出错误(我假设很常见的做法)会产生这种恐怖:
core.es5.js:1020 ERROR Error: Uncaught (in promise): baz
at resolvePromise (zone.js:824)
at resolvePromise (zone.js:795)
at zone.js:873
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:425)
at Object.onInvokeTask (core.es5.js:3881)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)
at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask (zone.js:192)
at drainMicroTaskQueue (zone.js:602)
at <anonymous>
问题
为什么我这次看不到堆栈跟踪或错误的来源? (我假设这只是因为JavaScript只是从抛出错误的位置生成堆栈跟踪?)
如果是这样,使用显式拒绝而不是在新Promise中抛出新错误是不好的做法吗?是否记录在某处,我错过了?
有什么方法可以解决这个问题吗? (获取堆栈跟踪并继续使用拒绝(...)而不是抛出错误?,我假设没有)
这是一个众所周知的问题/不良做法,我只是错过了备忘录?
答案 0 :(得分:0)
部分回答我自己的一个问题:
如果我将案例#3更改为:(包装在新的Error对象中)
ngOnInit() {
new Promise((resolve, reject) => {
reject(new Error("foo"));
}).then(() => {
console.log("ain't gonna happen");
});
}
然后,出乎意料的是,我确实得到了堆栈跟踪! (仅构造错误可以保存堆栈跟踪)
旁注...因为(我猜)我们大多数人都喜欢看堆栈跟踪而不是,为什么哦为什么不是这里提到的最佳做法?:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise < / p>
修改
为了确保我不会忘记,我添加了这个缩小范围(reject: (reason: Error) => void
而不是any
),不确定这是否是一个很好的解决方案,因为它不能防止传递{{1但它可以帮助保护一些未通过any
拒绝的案例。
Error