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

Commit 6ba3169

Browse files
JiaLiPassionmhevery
authored andcommitted
fix(bluebird): fix #1112, bluebird chained callback should return a Bluebird Promise (#1114)
1 parent 49e0548 commit 6ba3169

File tree

4 files changed

+175
-8
lines changed

4 files changed

+175
-8
lines changed

file-size-limit.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{
44
"path": "dist/zone.min.js",
55
"checkTarget": true,
6-
"limit": 42000
6+
"limit": 42050
77
}
88
]
99
}

lib/common/promise.ts

-5
Original file line numberDiff line numberDiff line change
@@ -476,11 +476,6 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr
476476

477477
if (NativePromise) {
478478
patchThen(NativePromise);
479-
480-
/*let fetch = global['fetch'];
481-
if (typeof fetch == 'function') {
482-
global['fetch'] = zoneify(fetch);
483-
}*/
484479
}
485480

486481
// This is not part of public API, but it is useful for tests, so we expose it.

lib/extra/bluebird.ts

+18-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,14 @@ Zone.__load_patch('bluebird', (global: any, Zone: ZoneType, api: _ZonePrivate) =
2525
args[i] = function() {
2626
const argSelf: any = this;
2727
const argArgs: any = arguments;
28-
zone.scheduleMicroTask('Promise.then', () => {
29-
return func.apply(argSelf, argArgs);
28+
return new Bluebird((res: any, rej: any) => {
29+
zone.scheduleMicroTask('Promise.then', () => {
30+
try {
31+
res(func.apply(argSelf, argArgs));
32+
} catch (error) {
33+
rej(error);
34+
}
35+
});
3036
});
3137
};
3238
}
@@ -35,6 +41,16 @@ Zone.__load_patch('bluebird', (global: any, Zone: ZoneType, api: _ZonePrivate) =
3541
});
3642
});
3743

44+
Bluebird.onPossiblyUnhandledRejection(function(e: any, promise: any) {
45+
try {
46+
Zone.current.runGuarded(() => {
47+
throw e;
48+
});
49+
} catch (err) {
50+
api.onUnhandledError(err);
51+
}
52+
});
53+
3854
// override global promise
3955
global[api.symbol('ZoneAwarePromise')] = Bluebird;
4056
};

test/extra/bluebird.spec.ts

+156
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
// this spec will not be integrated with Travis CI, because I don't
1010
// want to add bluebird into devDependencies, you can run this spec
1111
// on your local environment
12+
process.on('unhandledRejection', (reason, p) => {
13+
console.log('Unhandled Rejection at:', p, 'reason:', reason);
14+
// application specific logging, throwing an error, or other logic here
15+
});
1216

1317
describe('bluebird promise', () => {
1418
let BluebirdPromise: any;
@@ -636,4 +640,156 @@ describe('bluebird promise', () => {
636640
});
637641
});
638642
});
643+
644+
it('should be able to chain promise', (done: DoneFn) => {
645+
Zone.current.fork({name: 'zone_A'}).run(() => {
646+
new BluebirdPromise((resolve: any, reject: any) => {
647+
expect(Zone.current.name).toEqual('zone_A');
648+
resolve(1);
649+
})
650+
.then((r: any) => {
651+
expect(r).toBe(1);
652+
expect(Zone.current.name).toEqual('zone_A');
653+
return Promise.resolve(2);
654+
})
655+
.then((r: any) => {
656+
expect(r).toBe(2);
657+
expect(Zone.current.name).toEqual('zone_A');
658+
});
659+
});
660+
Zone.current.fork({name: 'zone_B'}).run(() => {
661+
new BluebirdPromise((resolve: any, reject: any) => {
662+
expect(Zone.current.name).toEqual('zone_B');
663+
reject(1);
664+
})
665+
.then(
666+
() => {
667+
fail('should not be here.');
668+
},
669+
(r: any) => {
670+
expect(r).toBe(1);
671+
expect(Zone.current.name).toEqual('zone_B');
672+
return Promise.resolve(2);
673+
})
674+
.then((r: any) => {
675+
expect(r).toBe(2);
676+
expect(Zone.current.name).toEqual('zone_B');
677+
done();
678+
});
679+
});
680+
});
681+
682+
it('should catch rejected chained bluebird promise', (done: DoneFn) => {
683+
const logs: string[] = [];
684+
const zone = Zone.current.fork({
685+
name: 'testErrorHandling',
686+
onHandleError: function() {
687+
// should not get here
688+
logs.push('onHandleError');
689+
return true;
690+
}
691+
});
692+
693+
zone.runGuarded(() => {
694+
return BluebirdPromise.resolve()
695+
.then(() => {
696+
throw new Error('test error');
697+
})
698+
.catch(() => {
699+
expect(logs).toEqual([]);
700+
done();
701+
});
702+
});
703+
});
704+
705+
it('should catch rejected chained global promise', (done: DoneFn) => {
706+
const logs: string[] = [];
707+
const zone = Zone.current.fork({
708+
name: 'testErrorHandling',
709+
onHandleError: function() {
710+
// should not get here
711+
logs.push('onHandleError');
712+
return true;
713+
}
714+
});
715+
716+
zone.runGuarded(() => {
717+
return Promise.resolve()
718+
.then(() => {
719+
throw new Error('test error');
720+
})
721+
.catch(() => {
722+
expect(logs).toEqual([]);
723+
done();
724+
});
725+
});
726+
});
727+
728+
it('should catch rejected bluebird promise', (done: DoneFn) => {
729+
const logs: string[] = [];
730+
const zone = Zone.current.fork({
731+
name: 'testErrorHandling',
732+
onHandleError: function() {
733+
// should not get here
734+
logs.push('onHandleError');
735+
return true;
736+
}
737+
});
738+
739+
zone.runGuarded(() => {
740+
return BluebirdPromise.reject().catch(() => {
741+
expect(logs).toEqual([]);
742+
done();
743+
});
744+
});
745+
});
746+
747+
it('should catch rejected global promise', (done: DoneFn) => {
748+
const logs: string[] = [];
749+
const zone = Zone.current.fork({
750+
name: 'testErrorHandling',
751+
onHandleError: function() {
752+
// should not get here
753+
logs.push('onHandleError');
754+
return true;
755+
}
756+
});
757+
758+
zone.runGuarded(() => {
759+
return Promise.reject(new Error('reject')).catch(() => {
760+
expect(logs).toEqual([]);
761+
done();
762+
});
763+
});
764+
});
765+
766+
it('should trigger onHandleError when unhandledRejection', (done: DoneFn) => {
767+
const zone = Zone.current.fork({
768+
name: 'testErrorHandling',
769+
onHandleError: function() {
770+
setTimeout(done, 100);
771+
return true;
772+
}
773+
});
774+
775+
zone.runGuarded(() => {
776+
return Promise.reject(new Error('reject'));
777+
});
778+
});
779+
780+
it('should trigger onHandleError when unhandledRejection in chained Promise', (done: DoneFn) => {
781+
const zone = Zone.current.fork({
782+
name: 'testErrorHandling',
783+
onHandleError: function() {
784+
setTimeout(done, 100);
785+
return true;
786+
}
787+
});
788+
789+
zone.runGuarded(() => {
790+
return Promise.resolve().then(() => {
791+
throw new Error('test');
792+
});
793+
});
794+
});
639795
});

0 commit comments

Comments
 (0)