Skip to content

Commit 2bb9a65

Browse files
JiaLiPassionmhevery
authored andcommitted
fix(zone.js): don't wrap uncaught promise error. (#31443)
Close #27840 PR Close #31443
1 parent 6b51ed2 commit 2bb9a65

File tree

3 files changed

+54
-21
lines changed

3 files changed

+54
-21
lines changed

packages/zone.js/lib/common/promise.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -176,20 +176,25 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr
176176
}
177177
if (queue.length == 0 && state == REJECTED) {
178178
(promise as any)[symbolState] = REJECTED_NO_CATCH;
179-
try {
180-
// try to print more readable error log
181-
throw new Error(
182-
'Uncaught (in promise): ' + readableObjectToString(value) +
183-
(value && value.stack ? '\n' + value.stack : ''));
184-
} catch (err) {
185-
const error: UncaughtPromiseError = err;
186-
error.rejection = value;
187-
error.promise = promise;
188-
error.zone = Zone.current;
189-
error.task = Zone.currentTask !;
190-
_uncaughtPromiseErrors.push(error);
191-
api.scheduleMicroTask(); // to make sure that it is running
179+
let uncaughtPromiseError: any;
180+
if (value instanceof Error || (value && value.message)) {
181+
uncaughtPromiseError = value;
182+
} else {
183+
try {
184+
// try to print more readable error log
185+
throw new Error(
186+
'Uncaught (in promise): ' + readableObjectToString(value) +
187+
(value && value.stack ? '\n' + value.stack : ''));
188+
} catch (err) {
189+
uncaughtPromiseError = err;
190+
}
192191
}
192+
uncaughtPromiseError.rejection = value;
193+
uncaughtPromiseError.promise = promise;
194+
uncaughtPromiseError.zone = Zone.current;
195+
uncaughtPromiseError.task = Zone.currentTask !;
196+
_uncaughtPromiseErrors.push(uncaughtPromiseError);
197+
api.scheduleMicroTask(); // to make sure that it is running
193198
}
194199
}
195200
}

packages/zone.js/test/common/Promise.spec.ts

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -345,11 +345,8 @@ describe(
345345
});
346346
setTimeout((): any => null);
347347
setTimeout(() => {
348-
expect(promiseError !.message)
349-
.toBe(
350-
'Uncaught (in promise): ' + error +
351-
(error !.stack ? '\n' + error !.stack : ''));
352348
expect((promiseError as any)['rejection']).toBe(error);
349+
expect(promiseError).toBe(error);
353350
expect((promiseError as any)['zone']).toBe(zone);
354351
expect((promiseError as any)['task']).toBe(task);
355352
done();
@@ -389,6 +386,39 @@ describe(
389386
});
390387
});
391388

389+
it('should print original information when throw a not error object with a message property',
390+
(done) => {
391+
let promiseError: Error|null = null;
392+
let zone: Zone|null = null;
393+
let task: Task|null = null;
394+
let rejectObj: TestRejection;
395+
queueZone
396+
.fork({
397+
name: 'promise-error',
398+
onHandleError: (delegate: ZoneDelegate, current: Zone, target: Zone, error: any):
399+
boolean => {
400+
promiseError = error;
401+
delegate.handleError(target, error);
402+
return false;
403+
}
404+
})
405+
.run(() => {
406+
zone = Zone.current;
407+
task = Zone.currentTask;
408+
rejectObj = new TestRejection();
409+
rejectObj.prop1 = 'value1';
410+
rejectObj.prop2 = 'value2';
411+
(rejectObj as any).message = 'rejectMessage';
412+
Promise.reject(rejectObj);
413+
expect(promiseError).toBe(null);
414+
});
415+
setTimeout((): any => null);
416+
setTimeout(() => {
417+
expect(promiseError).toEqual(rejectObj as any);
418+
done();
419+
});
420+
});
421+
392422
describe('Promise.race', () => {
393423
it('should reject the value', () => {
394424
queueZone.run(() => {

packages/zone.js/test/zone-spec/fake-async-test.spec.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,7 @@ describe('FakeAsyncTestZoneSpec', () => {
8484
() => {
8585
fakeAsyncTestZone.run(() => {
8686
Promise.resolve(null).then((_) => { throw new Error('async'); });
87-
expect(() => {
88-
testZoneSpec.flushMicrotasks();
89-
}).toThrowError(/Uncaught \(in promise\): Error: async/);
87+
expect(() => { testZoneSpec.flushMicrotasks(); }).toThrowError(/async/);
9088
});
9189
});
9290

@@ -1171,7 +1169,7 @@ const {fakeAsync, tick, discardPeriodicTasks, flush, flushMicrotasks} = fakeAsyn
11711169
resolvedPromise.then((_) => { throw new Error('async'); });
11721170
flushMicrotasks();
11731171
})();
1174-
}).toThrowError(/Uncaught \(in promise\): Error: async/);
1172+
}).toThrowError(/async/);
11751173
});
11761174

11771175
it('should complain if a test throws an exception', () => {

0 commit comments

Comments
 (0)