From 88052bf9fda3545416808ff61b3bce4ab40f1ed8 Mon Sep 17 00:00:00 2001 From: Chris Thielen Date: Thu, 8 Sep 2016 23:07:08 -0500 Subject: [PATCH] feat(redirect): Error after 20+ redirected transitions --- src/transition/transition.ts | 5 +++++ test/core/stateServiceSpec.ts | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/transition/transition.ts b/src/transition/transition.ts index a142c6683..6ba36c58c 100644 --- a/src/transition/transition.ts +++ b/src/transition/transition.ts @@ -551,6 +551,11 @@ export class Transition implements IHookRegistry { error() { let state: State = this.$to(); + let redirects = 0, trans: Transition = this; + while((trans = trans.redirectedFrom()) != null) { + if (++redirects > 20) return `Too many Transition redirects (20+)`; + } + if (state.self.abstract) return `Cannot transition to abstract state '${state.name}'`; if (!Param.validates(state.parameters(), this.params())) diff --git a/test/core/stateServiceSpec.ts b/test/core/stateServiceSpec.ts index 112af09f1..a219acdee 100644 --- a/test/core/stateServiceSpec.ts +++ b/test/core/stateServiceSpec.ts @@ -62,6 +62,21 @@ describe('stateService', function () { .then(done, done); })); + it('should error after 20+ redirects', (done) => { + let errors = []; + $transitions.onEnter({ entering: "D" }, trans => trans.router.stateService.target('D')); + $transitions.onError({}, trans => { errors.push(trans.error()) }); + + $state.defaultErrorHandler(function() {}); + + $state.go("D").catch(err => { + expect(errors.length).toBe(21); + expect(err.message).toContain('Too many Transition redirects'); + done(); + }); + }) + + it("should not update the URL in response to synchronizing URL", ((done) => { $loc.setUrl('/a/b/c'); spyOn($loc, 'setUrl').and.callThrough();