Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit fd1dfcc

Browse files
committed
fix(fakeAsync): throw error on rejected promisees.
1 parent 0621014 commit fd1dfcc

File tree

3 files changed

+26
-11
lines changed

3 files changed

+26
-11
lines changed

Diff for: lib/zone-spec/fake-async-test.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
private _scheduler: Scheduler = new Scheduler();
8181
private _microtasks: Function[] = [];
8282
private _lastError: Error = null;
83+
private _uncaughtPromiseErrors: {rejection: any}[] = Promise[Zone['__symbol__']('uncaughtPromiseErrors')];
8384

8485
pendingPeriodicTimers: number[] = [];
8586
pendingTimers: number[] = [];
@@ -172,7 +173,8 @@
172173
}
173174

174175
private _resetLastErrorAndThrow(): void {
175-
let error = this._lastError;
176+
let error = this._lastError || this._uncaughtPromiseErrors[0];
177+
this._uncaughtPromiseErrors.length = 0;
176178
this._lastError = null;
177179
throw error;
178180
}
@@ -188,14 +190,17 @@
188190

189191
flushMicrotasks(): void {
190192
FakeAsyncTestZoneSpec.assertInZone();
191-
while (this._microtasks.length > 0) {
192-
let microtask = this._microtasks.shift();
193-
microtask();
194-
if (this._lastError !== null) {
193+
const flushErrors = () => {
194+
if (this._lastError !== null || this._uncaughtPromiseErrors.length) {
195195
// If there is an error stop processing the microtask queue and rethrow the error.
196196
this._resetLastErrorAndThrow();
197197
}
198198
}
199+
while (this._microtasks.length > 0) {
200+
let microtask = this._microtasks.shift();
201+
microtask();
202+
}
203+
flushErrors();
199204
}
200205

201206
// ZoneSpec implementation below.

Diff for: lib/zone.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@ const Zone: ZoneType = (function(global: any) {
868868
let _currentTask: Task = null;
869869
let _microTaskQueue: Task[] = [];
870870
let _isDrainingMicrotaskQueue: boolean = false;
871-
let _uncaughtPromiseErrors: UncaughtPromiseError[] = [];
871+
const _uncaughtPromiseErrors: UncaughtPromiseError[] = [];
872872
let _drainScheduled: boolean = false;
873873

874874
function scheduleQueueDrain() {
@@ -894,7 +894,8 @@ const Zone: ZoneType = (function(global: any) {
894894
'Unhandled Promise rejection:', rejection instanceof Error ? rejection.message : rejection,
895895
'; Zone:', (<Zone>e.zone).name,
896896
'; Task:', e.task && (<Task>e.task).source,
897-
'; Value:', rejection
897+
'; Value:', rejection,
898+
rejection instanceof Error ? rejection.stack : undefined
898899
);
899900
}
900901
console.error(e);
@@ -916,10 +917,8 @@ const Zone: ZoneType = (function(global: any) {
916917
}
917918
}
918919
while(_uncaughtPromiseErrors.length) {
919-
const uncaughtPromiseErrors = _uncaughtPromiseErrors;
920-
_uncaughtPromiseErrors = [];
921-
for (let i = 0; i < uncaughtPromiseErrors.length; i++) {
922-
const uncaughtPromiseError: UncaughtPromiseError = uncaughtPromiseErrors[i];
920+
while(_uncaughtPromiseErrors.length) {
921+
const uncaughtPromiseError: UncaughtPromiseError = _uncaughtPromiseErrors.shift();
923922
try {
924923
uncaughtPromiseError.zone.runGuarded(() => { throw uncaughtPromiseError; });
925924
} catch (e) {
@@ -1119,5 +1118,7 @@ const Zone: ZoneType = (function(global: any) {
11191118
}
11201119
}
11211120

1121+
// This is not part of public API, but it is usefull for tests, so we expose it.
1122+
Promise[Zone.__symbol__('uncaughtPromiseErrors')] = _uncaughtPromiseErrors;
11221123
return global.Zone = Zone;
11231124
})(typeof window === 'undefined' ? global : window);

Diff for: test/zone-spec/fake-async-test.spec.ts

+9
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ describe('FakeAsyncTestZoneSpec', () => {
3030
fakeAsyncTestZone.run(() => { throw new Error('sync'); });
3131
}).toThrowError('sync');
3232
});
33+
34+
it('should throw error on Rejected promise', () => {
35+
expect(() => {
36+
fakeAsyncTestZone.run(() => {
37+
Promise.reject('myError')
38+
testZoneSpec.flushMicrotasks();
39+
});
40+
}).toThrowError('Uncaught (in promise): myError');
41+
});
3342
});
3443

3544
describe('asynchronous code', () => {

0 commit comments

Comments
 (0)