Searching for "Uncaught (in promise)" in Angular's github issues, google or here on stackoverflow yields a lot of very specific results, but my question is a bit more broad (and since the proliferation of results, I don't know if this is a duplicate)
Premise: somewhere in my code I have an uncaught promise rejection (Angular 4.4.4)
Cases:
Case 1: Simple Rejection
In MyComponent:
ngOnInit() {
Promise.reject("foo");
}
Yields this in the console (great, I can see where it came from):
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)
Case 2: new Promise, throwing an error
In MyComponent:
ngOnInit() {
new Promise((resolve, reject) => {
throw new Error("foo");
}).then(() => {
console.log("ain't gonna happen");
});
}
Yields this in the console (even better, gives away the location right on the spot):
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)
This also works with chaining, e.g. the following gives the same stack trace more or less in the console.
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));
}
Case 3: Using reject(...)
In MyComponent:
ngOnInit() {
new Promise((resolve, reject) => {
reject("foo");
}).then(() => {
console.log("ain't gonna happen");
});
}
Changing throwing an error to the (I assume pretty common practice) of using the promise's reject method, yields this horror:
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>
Question
Why can't I see the stack trace or the origin of the error this time? (I assume it's due to simply JavaScript only generating stack trace from the location of the Error thrown?)
If so, is it bad practice to use explicit reject over throwing a new Error in a new Promise? Is it documented somewhere and I missed it?
Is there any way to fix this? (get the stack trace and keep using reject(...) instead of throwing an Error?, I assume no)
Is this a well known issue / bad practice and I just missed the memo?