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

Commit

Permalink
fix(fakeAsync): throw error on rejected promisees.
Browse files Browse the repository at this point in the history
  • Loading branch information
mhevery committed Aug 15, 2016
1 parent 0621014 commit fd1dfcc
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 11 deletions.
15 changes: 10 additions & 5 deletions lib/zone-spec/fake-async-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
private _scheduler: Scheduler = new Scheduler();
private _microtasks: Function[] = [];
private _lastError: Error = null;
private _uncaughtPromiseErrors: {rejection: any}[] = Promise[Zone['__symbol__']('uncaughtPromiseErrors')];

pendingPeriodicTimers: number[] = [];
pendingTimers: number[] = [];
Expand Down Expand Up @@ -172,7 +173,8 @@
}

private _resetLastErrorAndThrow(): void {
let error = this._lastError;
let error = this._lastError || this._uncaughtPromiseErrors[0];
this._uncaughtPromiseErrors.length = 0;
this._lastError = null;
throw error;
}
Expand All @@ -188,14 +190,17 @@

flushMicrotasks(): void {
FakeAsyncTestZoneSpec.assertInZone();
while (this._microtasks.length > 0) {
let microtask = this._microtasks.shift();
microtask();
if (this._lastError !== null) {
const flushErrors = () => {
if (this._lastError !== null || this._uncaughtPromiseErrors.length) {
// If there is an error stop processing the microtask queue and rethrow the error.
this._resetLastErrorAndThrow();
}
}
while (this._microtasks.length > 0) {
let microtask = this._microtasks.shift();
microtask();
}
flushErrors();
}

// ZoneSpec implementation below.
Expand Down
13 changes: 7 additions & 6 deletions lib/zone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,7 @@ const Zone: ZoneType = (function(global: any) {
let _currentTask: Task = null;
let _microTaskQueue: Task[] = [];
let _isDrainingMicrotaskQueue: boolean = false;
let _uncaughtPromiseErrors: UncaughtPromiseError[] = [];
const _uncaughtPromiseErrors: UncaughtPromiseError[] = [];
let _drainScheduled: boolean = false;

function scheduleQueueDrain() {
Expand All @@ -894,7 +894,8 @@ const Zone: ZoneType = (function(global: any) {
'Unhandled Promise rejection:', rejection instanceof Error ? rejection.message : rejection,
'; Zone:', (<Zone>e.zone).name,
'; Task:', e.task && (<Task>e.task).source,
'; Value:', rejection
'; Value:', rejection,
rejection instanceof Error ? rejection.stack : undefined
);
}
console.error(e);
Expand All @@ -916,10 +917,8 @@ const Zone: ZoneType = (function(global: any) {
}
}
while(_uncaughtPromiseErrors.length) {
const uncaughtPromiseErrors = _uncaughtPromiseErrors;
_uncaughtPromiseErrors = [];
for (let i = 0; i < uncaughtPromiseErrors.length; i++) {
const uncaughtPromiseError: UncaughtPromiseError = uncaughtPromiseErrors[i];
while(_uncaughtPromiseErrors.length) {
const uncaughtPromiseError: UncaughtPromiseError = _uncaughtPromiseErrors.shift();
try {
uncaughtPromiseError.zone.runGuarded(() => { throw uncaughtPromiseError; });
} catch (e) {
Expand Down Expand Up @@ -1119,5 +1118,7 @@ const Zone: ZoneType = (function(global: any) {
}
}

// This is not part of public API, but it is usefull for tests, so we expose it.
Promise[Zone.__symbol__('uncaughtPromiseErrors')] = _uncaughtPromiseErrors;
return global.Zone = Zone;
})(typeof window === 'undefined' ? global : window);
9 changes: 9 additions & 0 deletions test/zone-spec/fake-async-test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ describe('FakeAsyncTestZoneSpec', () => {
fakeAsyncTestZone.run(() => { throw new Error('sync'); });
}).toThrowError('sync');
});

it('should throw error on Rejected promise', () => {
expect(() => {
fakeAsyncTestZone.run(() => {
Promise.reject('myError')
testZoneSpec.flushMicrotasks();
});
}).toThrowError('Uncaught (in promise): myError');
});
});

describe('asynchronous code', () => {
Expand Down

0 comments on commit fd1dfcc

Please sign in to comment.