angular-cn/packages/zone.js/test/common/promise-disable-wrap-uncaught-promise-rejection.spec.ts
JiaLiPassion 19d543f71e fix(zone.js): disable wrap uncaught promise rejection should handle primitive value (#38476)
Close #38334.

zone.js provides a flag DISABLE_WRAPPING_UNCAUGHT_PROMISE_REJECTION to let zone.js
throw the original error instead of wrap it when uncaught promise rejection found.
But the rejection value could be anything includes primitive value such as number.
In that case, we should not attach any additional properties to the value.

PR Close #38476
2020-09-24 11:32:44 -04:00

103 lines
3.1 KiB
TypeScript

/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
class TestRejection {
prop1?: string;
prop2?: string;
}
describe('disable wrap uncaught promise rejection', () => {
it('should notify Zone.onHandleError if promise is uncaught', (done) => {
let promiseError: Error|null = null;
let zone: Zone|null = null;
let task: Task|null = null;
let error: Error|null = null;
Zone.current
.fork({
name: 'promise-error',
onHandleError: (delegate: ZoneDelegate, current: Zone, target: Zone, error: any):
boolean => {
promiseError = error;
delegate.handleError(target, error);
return false;
}
})
.run(() => {
zone = Zone.current;
task = Zone.currentTask;
error = new Error('rejectedErrorShouldBeHandled');
try {
// throw so that the stack trace is captured
throw error;
} catch (e) {
}
Promise.reject(error);
expect(promiseError).toBe(null);
});
setTimeout((): any => null);
setTimeout(() => {
expect(promiseError).toBe(error);
expect((promiseError as any)['rejection']).toBe(undefined);
expect((promiseError as any)['zone']).toBe(undefined);
expect((promiseError as any)['task']).toBe(undefined);
done();
});
});
it('should print original information when a non-Error object is used for rejection', (done) => {
let promiseError: Error|null = null;
let rejectObj: TestRejection;
Zone.current
.fork({
name: 'promise-error',
onHandleError: (delegate: ZoneDelegate, current: Zone, target: Zone, error: any):
boolean => {
promiseError = error;
delegate.handleError(target, error);
return false;
}
})
.run(() => {
rejectObj = new TestRejection();
rejectObj.prop1 = 'value1';
rejectObj.prop2 = 'value2';
(rejectObj as any).message = 'rejectMessage';
Promise.reject(rejectObj);
expect(promiseError).toBe(null);
});
setTimeout((): any => null);
setTimeout(() => {
expect(promiseError).toEqual(rejectObj as any);
done();
});
});
it('should print original information when a primitive value is used for rejection', (done) => {
let promiseError: number|null = null;
Zone.current
.fork({
name: 'promise-error',
onHandleError: (delegate: ZoneDelegate, current: Zone, target: Zone, error: any):
boolean => {
promiseError = error;
delegate.handleError(target, error);
return false;
}
})
.run(() => {
Promise.reject(42);
expect(promiseError).toBe(null);
});
setTimeout((): any => null);
setTimeout(() => {
expect(promiseError).toBe(42);
done();
});
});
});