This repository was archived by the owner on Apr 12, 2024. It is now read-only.
File tree Expand file tree Collapse file tree 3 files changed +48
-3
lines changed
Expand file tree Collapse file tree 3 files changed +48
-3
lines changed Original file line number Diff line number Diff line change 1+ @ngdoc error
2+ @name $q:qcycle
3+ @fullName Cannot resolve a promise with itself
4+ @description
5+
6+ Occurs when resolving a promise with itself as the value, including returning the promise in a
7+ function passed to `then`. The A+ 1.1 spec mandates that this behavior throw a TypeError.
8+ https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
9+
10+ ```
11+ var promise = $q.defer().promise;
12+
13+ //bad
14+ promise.then(function (val) {
15+ //Cannot return self
16+ return promise;
17+ });
18+
19+ //good
20+ promise.then(function (val) {
21+ return 'some other value';
22+ });
23+ ```
Original file line number Diff line number Diff line change @@ -235,7 +235,7 @@ function $$QProvider() {
235235 * @returns {object } Promise manager.
236236 */
237237function qFactory ( nextTick , exceptionHandler ) {
238- var $qMinErr = minErr ( '$q' ) ;
238+ var $qMinErr = minErr ( '$q' , TypeError ) ;
239239 function callOnce ( self , resolveFn , rejectFn ) {
240240 var called = false ;
241241 function wrap ( fn ) {
@@ -338,8 +338,16 @@ function qFactory(nextTick, exceptionHandler) {
338338 Deferred . prototype = {
339339 resolve : function ( val ) {
340340 if ( this . promise . $$state . status ) return ;
341- if ( val === this . promise ) throw new TypeError ( 'Cycle detected' ) ;
342- this . $$resolve ( val ) ;
341+ if ( val === this . promise ) {
342+ this . $$reject ( $qMinErr (
343+ 'qcycle' ,
344+ "Expected promise to be resolved with value other than itself '{0}'" ,
345+ val ) ) ;
346+ }
347+ else {
348+ this . $$resolve ( val ) ;
349+ }
350+
343351 } ,
344352
345353 $$resolve : function ( val ) {
Original file line number Diff line number Diff line change @@ -815,6 +815,20 @@ describe('q', function() {
815815 } ) ;
816816
817817
818+ it ( 'should complain if promise fulfilled with itself' , function ( ) {
819+ var resolveSpy = jasmine . createSpy ( 'resolve' ) ;
820+ var rejectSpy = jasmine . createSpy ( 'reject' ) ;
821+ promise . then ( resolveSpy , rejectSpy ) ;
822+ deferred . resolve ( deferred . promise ) ;
823+ mockNextTick . flush ( ) ;
824+
825+ expect ( resolveSpy ) . not . toHaveBeenCalled ( ) ;
826+ expect ( rejectSpy ) . toHaveBeenCalled ( ) ;
827+ expect ( rejectSpy . calls [ 0 ] . args [ 0 ] . message ) .
828+ toMatch ( / \[ \$ q \: q c y c l e \] E x p e c t e d p r o m i s e t o b e r e s o l v e d w i t h v a l u e o t h e r t h a n i t s e l f / ) ;
829+ } ) ;
830+
831+
818832 it ( 'should do nothing if a promise was previously resolved' , function ( ) {
819833 promise . then ( success ( ) , error ( ) ) ;
820834 expect ( logStr ( ) ) . toBe ( '' ) ;
You can’t perform that action at this time.
0 commit comments