Skip to content

Commit fc557f0

Browse files
atscottmattrbeck
authored andcommitted
fix(zone.js): support passthrough of Promise.try API
When Zone patches Promise, it uses ZoneAwarePromise. The new Promise.try API was undefined on ZoneAwarePromise, making it unavailable when zone was present. This change gracefully passes through Promise.try to the native Promise implementation, if available, without patching it to execute in the right zone (our stance is not to add new patches but avoid destructively making new APIs unavailable). Fixes #67057
1 parent 95b3f37 commit fc557f0

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,11 @@ export function patchPromise(Zone: ZoneType): void {
627627

628628
if (NativePromise) {
629629
patchThen(NativePromise);
630+
// TODO(atscott): Investigate generic to propagate any unknown properties
631+
const nativeTry = (NativePromise as any)['try'];
632+
if (nativeTry && typeof nativeTry === 'function') {
633+
(ZoneAwarePromise as any)['try'] = nativeTry;
634+
}
630635
patchMethod(global, 'fetch', (delegate) => zoneify(delegate));
631636
}
632637

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,5 +969,38 @@ describe(
969969
reject(error);
970970
});
971971
});
972+
973+
describe('Promise.try', () => {
974+
it('should resolve', (done: DoneFn) => {
975+
(Promise as any)
976+
.try(() => 1)
977+
.then((v: any) => {
978+
expect(v).toBe(1);
979+
done();
980+
});
981+
});
982+
it('should reject on throw', (done: DoneFn) => {
983+
const error = new Error('test');
984+
(Promise as any)
985+
.try(() => {
986+
throw error;
987+
})
988+
.catch((e: any) => {
989+
expect(e).toBe(error);
990+
done();
991+
});
992+
});
993+
it('should execute in the correct zone', (done: DoneFn) => {
994+
const zone = Zone.current.fork({name: 'promise-try'});
995+
zone.run(() => {
996+
(Promise as any)
997+
.try(() => 1)
998+
.then(() => {
999+
expect(Zone.current.name).toEqual(zone.name);
1000+
done();
1001+
});
1002+
});
1003+
});
1004+
});
9721005
}),
9731006
);

packages/zone.js/test/test_fake_polyfill.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,19 @@ export function setupFakePolyfill(): void {
1717
NativeError.customProperty = 'customProperty';
1818
NativeError.customFunction = function () {};
1919

20+
// Polyfill Promise.try for testing pass-through
21+
if (global.Promise && typeof global.Promise.try !== 'function') {
22+
global.Promise.try = function (callback: any) {
23+
return new global.Promise((resolve: any, reject: any) => {
24+
try {
25+
resolve(callback());
26+
} catch (e) {
27+
reject(e);
28+
}
29+
});
30+
};
31+
}
32+
2033
// add fake cordova polyfill for test
2134
const fakeCordova = function () {};
2235

0 commit comments

Comments
 (0)