diff --git a/packages/zone.js/lib/common/promise.ts b/packages/zone.js/lib/common/promise.ts index d561ae6be9d..7eca3b29958 100644 --- a/packages/zone.js/lib/common/promise.ts +++ b/packages/zone.js/lib/common/promise.ts @@ -627,6 +627,11 @@ export function patchPromise(Zone: ZoneType): void { if (NativePromise) { patchThen(NativePromise); + // TODO(atscott): Investigate generic to propagate any unknown properties + const nativeTry = (NativePromise as any)['try']; + if (nativeTry && typeof nativeTry === 'function') { + (ZoneAwarePromise as any)['try'] = nativeTry; + } patchMethod(global, 'fetch', (delegate) => zoneify(delegate)); } diff --git a/packages/zone.js/test/common/Promise.spec.ts b/packages/zone.js/test/common/Promise.spec.ts index 9257f740ebc..29533a3df32 100644 --- a/packages/zone.js/test/common/Promise.spec.ts +++ b/packages/zone.js/test/common/Promise.spec.ts @@ -969,5 +969,38 @@ describe( reject(error); }); }); + + describe('Promise.try', () => { + it('should resolve', (done: DoneFn) => { + (Promise as any) + .try(() => 1) + .then((v: any) => { + expect(v).toBe(1); + done(); + }); + }); + it('should reject on throw', (done: DoneFn) => { + const error = new Error('test'); + (Promise as any) + .try(() => { + throw error; + }) + .catch((e: any) => { + expect(e).toBe(error); + done(); + }); + }); + it('should execute in the correct zone', (done: DoneFn) => { + const zone = Zone.current.fork({name: 'promise-try'}); + zone.run(() => { + (Promise as any) + .try(() => 1) + .then(() => { + expect(Zone.current.name).toEqual(zone.name); + done(); + }); + }); + }); + }); }), ); diff --git a/packages/zone.js/test/test_fake_polyfill.ts b/packages/zone.js/test/test_fake_polyfill.ts index 34f12bdcdfb..b60ad768574 100644 --- a/packages/zone.js/test/test_fake_polyfill.ts +++ b/packages/zone.js/test/test_fake_polyfill.ts @@ -17,6 +17,19 @@ export function setupFakePolyfill(): void { NativeError.customProperty = 'customProperty'; NativeError.customFunction = function () {}; + // Polyfill Promise.try for testing pass-through + if (global.Promise && typeof global.Promise.try !== 'function') { + global.Promise.try = function (callback: any) { + return new global.Promise((resolve: any, reject: any) => { + try { + resolve(callback()); + } catch (e) { + reject(e); + } + }); + }; + } + // add fake cordova polyfill for test const fakeCordova = function () {};