Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

redirectTo causing The transition has been superseded by a different transition errors #3309

Closed
milo- opened this issue Jan 31, 2017 · 50 comments

Comments

@milo-
Copy link

milo- commented Jan 31, 2017

I'm getting a possibly handled rejection when a state redirects to itself with new parameters. The error is {"type":2,"message":"The transition has been superseded by a different transition", detail:... "redirected": true} Even though the error is logged, the transition continues as expected.

The error is uncaught in appendHookToChain (transition.js:604). It also does not come through the defaultErrorHandler so I have no way of stopping the error logging to the console. Stacktrace:

screen shot 2017-01-31 at 16 38 41

I'm using angular 1.6.1 and ui-router 1.0.0-rc.1. I've been trying to reproduce in plnkr but I'm having no luck.

@smhc
Copy link

smhc commented Feb 2, 2017

I am seeing similar behaviour. More details: #2676 (comment)

This plunkr reproduces the problem: http://plnkr.co/edit/3Fp38M?p=preview

Note use of multiple hooks and timeout promises.. I couldn't reproduce it without those. I suspect there may be a race condition in the 'reject silencing' that doesn't work if the promise doesn't resolve immediately.. or maybe the catching of rejected promises needs to work for the full chain when there are multiple transition hooks.

@kutu
Copy link

kutu commented Feb 13, 2017

i have the same issue with redirectTo
angular 1.6.1 and ui-router 1.0.0-rc.1 (also tried beta.3)

i tried recreate issue, but unsuccessful
this is what i have so far http://embed.plnkr.co/2CqGiKHtKMdmkRXQtCxM/

in my real app, when i switch between b anc c url, issue appear
if i comment data.menu, or ng-repeat links in a.html, no issue appear

part of error from real app
capture

$trace enabled
click link for the first time

Transition #0 r0: Started  -> "Transition#0( ''{} -> 'server.stream-overlay'{} )"
Transition #0 r0: <- Rejected "Transition#0( ''{} -> 'server.stream-overlay'{} )", reason: TransitionRejection(type: 2, message: The transition has been superseded by a different transition, detail: 'server.stream-overlay.index'{"#":null})
Transition #1 r0: Started  -> "Transition#1( ''{} -> 'server.stream-overlay.index'{} )"
Transition #1 r0: <- Success  "Transition#1( ''{} -> 'server.stream-overlay.index'{} )", final state: server.stream-overlay.index

clicking 2nd time same link

Transition #2 r0: Started  -> "Transition#2( 'server.stream-overlay.index'{} -> 'server.stream-overlay'{} )"
Transition #2 r0: <- Rejected "Transition#2( 'server.stream-overlay.index'{} -> 'server.stream-overlay'{} )", reason: TransitionRejection(type: 2, message: The transition has been superseded by a different transition, detail: 'server.stream-overlay.index'{"#":null})
Transition #3 r0: Ignored  <> "Transition#3( 'server.stream-overlay.index'{} -> 'server.stream-overlay.index'{} )"

only 2nd click and following clicks on the same link gives the error

@christopherthielen
Copy link
Contributor

christopherthielen commented Mar 14, 2017

I believe this will be fixed in rc.2by ui-router/core@a7464bb

http://plnkr.co/edit/HrJKJP?p=preview

@photocurio
Copy link

why close the issue when the fix has not even been released? we can't test it.

@christopherthielen
Copy link
Contributor

why close the issue when the fix has not even been released? we can't test it.

Because the code that fixes the issue is committed to the master branch. This is how issue trackers work normally, isn't it?

@roymap
Copy link

roymap commented May 13, 2017

I'm still getting this error. Using 1.0.3.

@4O4
Copy link

4O4 commented May 15, 2017

I've just updated to 1.0.3 and it doesn't work for me with following configuration:

url: '',
redirectTo: 'some.nested.state',
component: 'app',

But after removing component it started to work fine:

url: '',
redirectTo: 'some.nested.state',

So I just ended up using the second config and additional abstract state for app component.

@Anber
Copy link

Anber commented May 17, 2017

A problem is still there. I have one state with ui-sref-active in the template and another with a redirect to a third state. But everything works properly if I remove ui-sref-active from the template of the first state.

@Anber
Copy link

Anber commented May 17, 2017

2017-05-17 15 54 27

In my case, angular throws 3 "Possible unhandled rejection". Two of them can be fixed by adding onRejecting-callback to line trans.promise.then(update) in stateDirective, but I can't catch the last one rejection.

@christopherthielen
Copy link
Contributor

@4O4 very interesting, and not expected.

@christopherthielen
Copy link
Contributor

@Anber can you help me reproduce this in a plunker? http://bit.ly/UIR-Plunk1

@Anber
Copy link

Anber commented May 18, 2017

@christopherthielen, I had been trying to reproduce it a whole day and I had begun to think that there is a problem in one of my deep tweaks of the router, but then I found one strange thing: in some cases a behaviour of the transitionService.onStart depends on the presence of ui-sref-active in the view's template. Unfortunately, I can't reproduce it in a plunker, but I can try to describe everything that I found and maybe you help me to understand what I missed.
I've found two required conditions:

  1. source state should have ui-sref-active in the view's template;
  2. target state should have redirectTo.

In my application, transition from source to target state produces following trace log:
2017-05-17 17 03 31

If I remove ui-sref-active from source state (or just comment line with $uiRouter.transitionService.onStart in stateDirectives), transition produces following log:
2017-05-17 17 04 27

How you can see, there is one small difference in additional to error: unexpected call of transitionService.onStart at app.js:98. This is the onStart which I mentioned before and it's just a global handler for all transitions app.run($uiRouter => $uiRouter.transitionService.onStart({}, trans => console.log('transitionService.onStart', trans)));. I can't understand how two unrelated transitionService.onStart can affect to each other. Can you explain it?

http://plnkr.co/edit/cMnR7lD40hPqW5PsZ8uK?p=preview it's a very simplified structure of my application.

Visualization of both transitions looks absolutely the same.
2017-05-18 12 16 29

@erikbaan
Copy link

erikbaan commented May 28, 2017

Can confirm this also happens when transitioning to a child state using 1.0.3.

Run block:

    $transitions.onBefore({ to: 'search' }, function(trans) {
        return trans.router.stateService.target('search.results.list', trans.targetState().params());
    });

Results in:

Transition #0-0: <- Rejected "Transition#0( ''{} -> 'search'{"searchId":"ae5c8d9415c5e822ac1e2272fca8a298"} )", reason: Transition Rejection($id: 0 type: 2, message: The transition has been superseded by a different transition, detail: 'search.results.list'{"searchId":"ae5c8d9415c5e822ac1e2272fca8a298"})
stateListener.js:28 stateListener.onError e {_deferred: Deferred, promise: Promise, _registeredHooks: Object, _hookBuilder: e, isActive: function…}
angular-ui-router.min.js:11 Transition #1-0: Started  -> "Transition#1( ''{} -> 'search.results.list'{"searchId":"ae5c8d9415c5e822ac1e2272fca8a298"} )"

Also happens when returning a promise which resolves to a target state.

Navigating between parent and child state in this example will demonstrate the issue:

<!DOCTYPE html>
<html>

<head>
    <script data-require="angular.js@1.6.2" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
    <script data-require="ui-router@1.0.0-alpha.4" data-semver="1.0.0-alpha.4" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.3/angular-ui-router.min.js"></script>
    <script type="text/javascript">
        angular.module('demo', ['ui.router']);

        angular.module('demo').config(function($stateProvider, $locationProvider) {
            $locationProvider.html5Mode(false);

            $stateProvider.state({
                name: 'parent',
                template: 'parent',
                url: '/parent/:a'
            });

            $stateProvider.state({
                name: 'parent.child',
                template: 'child',
                url: '/child'
            });
        });

        angular.module('demo').run(function($transitions) {
            $transitions.onError({}, function(transition) {
                console.log('error', transition.error().message, transition);
            });

            $transitions.onBefore({ to: 'parent' }, function(trans) {
                console.log(trans.targetState().name());
                return trans.router.stateService.target('parent.child', trans.targetState().params());
            });
        });

        angular.module('demo').controller('main', function($state, $stateParams, $location) {
            this.params = $stateParams;
//            console.log('main', $state.current, $location);
        });
    </script>
</head>

<body ng-app="demo" ng-controller="main as $ctrl">
<ui-view></ui-view>

<ul>
<li><a href="#/parent" ui-sref="parent({a: 1})">parent:a = 1</a></li>
<li><a href="#/parent/child" ui-sref="parent.child({a: 2})">parent.child:a = 2</a></li>
</ul>

{{ $ctrl.params | json }}<br><br>

</body>
</html>

@christopherthielen
Copy link
Contributor

Navigating between parent and child state in this example will demonstrate the issue:

@erikbaan thanks for providing an example. In your example, the onError hook is logging the message and the transition.

Is this the problem you're describing? That a redirected transition is triggering the onError hook?

If so, I'm afraid that's by design. When a transition is run, it will either fire the onSuccess or the onError hooks. Redirecting a transition does not mutate it. Instead, the original transition is superseded (and thus, it is cancelled) by a new transition which targets the redirected-to state.

The original transition to parent is not successful because the state machine didn't transition to the parent state. Instead, it cancelled the old transition and started a new transition to parent.child.

If you have a global onError hook, you should filter out errors that you do not want to handle. In this case, check transition.error().redirected

@christopherthielen
Copy link
Contributor

@Anber that's some good sleuthing. I'm still not sure how to reproduce this though :(

@christopherthielen
Copy link
Contributor

I think we all owe @aj-dev some thanks for tracking this down in #3404 A fix should be coming soon.

@christopherthielen
Copy link
Contributor

1.0.4 is released

@morungos
Copy link

Thanks all, this fixes the issue nicely for me 🎉

@Anber
Copy link

Anber commented Jun 11, 2017

unhandled rejection has gone, but onStart is still called twice. I will open new issue when I can reproduce it.

@christopherthielen
Copy link
Contributor

@Anber redirectTo is an onStart hook (with default priority). Your onStart hook is probably also a default priority hook. Try raising or lowering the priority and see if the behavior changes. { priority: 1 } or { priority: -1 }

@Anber
Copy link

Anber commented Jun 12, 2017

@christopherthielen, how I said before, it does not depend on redirectTo, it depends on ui-sref-active: onStart hook called twice if view's template contains ui-sref-active and called once if not. And priority changing doesn't affect on this situation: it still called twice in case of redirect from a page with ui-sref-active.

@realph
Copy link

realph commented Jun 15, 2017

@christopherthielen Thanks for this fix. Any idea on when 1.0.4 will hit npm?

Edit: Ahh it seems the build failed.

@rodney757
Copy link

@christopherthielen I'm have the same issue as @Anber

@haoyongliang
Copy link

thanks ,and I'm using angular version 1.6, angular-ui-router is 1.0.4, the problem still exists,

@adamreisnz
Copy link

adamreisnz commented Jun 24, 2017

@christopherthielen Any chance of 1.0.4 landing on npm soon? Kind of need this fix in our next production release which is happening very soon. You mention it's been released 14 days ago but npm still says last version is 1.0.3

@guillaumevincent
Copy link

guillaumevincent commented Jun 26, 2017

@adamreisnz are you sure?
did you run npm install @uirouter/angularjs? it returns version 1.0.4 for me @uirouter/angularjs@1.0.4

remember angular-ui-router has been renamed to @uirouter/angularjs.

@adamreisnz
Copy link

adamreisnz commented Jun 26, 2017

Renamed to what? @uirouter/angularjs?

No, I was still looking at https://www.npmjs.com/package/angular-ui-router ...

It would have been great to have this communicated on the old npm page and add a deprecation warning to that package. One does not... simply rename the package and leave the old one up without warning ;)

@guillaumevincent
Copy link

guillaumevincent commented Jun 26, 2017

@adamreisnz a npm install angular-ui-router returns:

WARNING! this npm package "angular-ui-router" has been renamed to "@uirouter/angularjs".  Please update your package.json
See https://ui-router.github.io/blog/uirouter-scoped-packages/ for details.

@adamreisnz
Copy link

Hmmm, I use yarn. It seems such words of warning are not uttered by it when installing. I will raise an issue for it there.

@adamreisnz
Copy link

adamreisnz commented Jun 26, 2017

Ok actually the issue does lie in this package. The warning message is logged by plain console logs during installation, but all of this gets swallowed by yarn if there is no 1 exit code.

Instead, this command should be used to deprecate the package properly, so that users can be warned regardless of them using npm or yarn:

https://docs.npmjs.com/cli/deprecate

There's many yarn users out there, they will miss out on this warning if it's not properly deprecated. I will raise a separate issue for it though to not further derail this thread.

@burka
Copy link

burka commented Jan 23, 2018

I am using @uirouter/angularjs version 1.0.13 and have the same error:

stateService.js?9312:41 Transition Rejection($id: 0 type: 2, 
  message: The transition has been superseded by a different transition, 
  detail: Transition#1( ''{} -> 'back'{"error":"null","errors":"null"} )
)

or

stateService.js?9312:41 Transition Rejection($id: 0 type: 2, 
  message: The transition has been superseded by a different transition, 
  detail: "null"
)

@sixinli
Copy link

sixinli commented Jan 23, 2018

on 1.0.11 and seeing this too

@dunecatnat
Copy link

the same for us, using v1.0.13
in $transtion$.onStart() we are verifying for certain conditions, and then redirecting accordingly or not redirecting at all.
if we use transition.abort() before verifying for any conditions before redirecting, we get

Possibly unhandled rejection: {"$id":4,"type":3,"message":"The transition has been aborted","detail":"Hook aborted transition"}

if we remove transition.abort() we get

angular.js?58d0:14791 Possibly unhandled rejection: {"$id":5,"type":2,"message":"The transition has been superseded by a different transition","detail":null}

@aenriquezgentile
Copy link

Using v1.0.14 and seeing "The transition has been superseded by a different transition" error too.

This answer https://stackoverflow.com/a/44654316 removes the error for me, but I would not like to add timeouts for every $state.go redirection.

@dredmonds
Copy link

I am currently using version 1.0.14 using angular 1.6.x it give similar error when refreshing the page.

@adamreisnz
Copy link

Same here, we upgraded recently and we're logging a lot of these errors in Sentry:

Possibly unhandled rejection: {"$id":0,"type":2,"message":"The transition has been superseded by a different transition"

@christopherthielen Is this a regression from the earlier fix?

@fpoljak
Copy link

fpoljak commented Mar 12, 2018

Same here on 1.0.15

@Jisay
Copy link

Jisay commented Apr 12, 2018

Same too on 1.0.17

@Eddie541
Copy link

I get this when navigating through an abstract route on page refresh. Removing the abstract property on the parent route 'fixed' the issue.

@skyzito
Copy link

skyzito commented May 23, 2018

same on 1.0.16

@wiadev
Copy link

wiadev commented May 24, 2018

I'm having same issue as well.

angularjs 1.6.7
angular-ui-router: 1.0. 18

I'm getting the following error.

Transition Rejection($id: 0 type: 2, message: The transition has been superseded by a different transition, detail: "null")

it was caused by $state.go('login').

@jacebot
Copy link

jacebot commented Jun 12, 2018

So I found that using the .go() method causes the transitions error when attempting to employ the user auth example. I have a service that is promising to return a user, if it errors, I redirect the user to login.

When using return trans.router.stateService.target('app.login'); nothing would happen

When using return trans.router.stateService.go('app.login'); or using return $state.go('app.login'); would cause the transition error, but would redirect where I wanted it to.

When using return trans.router.stateService.transitionTo('app.login'); WINNER!!

No error, and redirected as expected.

UPDATE: Also I notice when passing a specified route parent like the example I could sometimes throw the error when attempting to access a protected route. However, using this seemed to resolve it as expected thus far. $transitions.onStart({},... . where the example uses$transitions.onStart({to: 'app.**' },...

Hope this helps.

AngularJS - 1.7.1
@ui-router -1.0.18

@adamreisnz
Copy link

adamreisnz commented Jun 13, 2018

For me returning transition.router.stateService.target('foo', params); works ok for redirection, also in the case of unauthenticated routes. I think it is the preferred approach, and using transitionTo instead may have unintended consequences? Not 100% sure but would be worthwhile to double check.

@adamreisnz
Copy link

This appears fixed again in ui-router 1.0.19 and core 5.0.20. I'm seeing the messages of superseded transitions in the console, but they aren't triggering an unhandled exception. Will deploy to production shortly and report back if it still errors.

@adamreisnz
Copy link

adamreisnz commented Jul 24, 2018

Looks like this is still occasionally triggering an exception in our live environment. Have added the following filter to block these out:

        if (
          typeof exception === 'object' &&
          typeof exception.message === 'string' &&
          exception.message.match(/^Possibly unhandled.+The transition errored/)
        ) {
          return;
        }

@magbicaleman
Copy link

In version 1.0.20, I'm seeing this when the application is slow to load, and the navigation is available for a user to try to go to a different state. Should this be considered an error at all when getting displayed in the console, perhaps the techniques that we're using are not as per recommended?

@j-walker23
Copy link

That seems bad, considering lazy loading.

@fishbone1
Copy link

We still have this problem with 1.0.25. Unfortunately we don't use $state.go(). We just have redirectTo in our routing configuration.

@galihsetyo
Copy link

use $state.dispose() before $state.go()

@WLyKan
Copy link

WLyKan commented Oct 21, 2021

I'm having same issue as well.

angularjs 1.6.7 angular-ui-router: 1.0. 18

I'm getting the following error.

Transition Rejection($id: 0 type: 2, message: The transition has been superseded by a different transition, detail: "null")

it was caused by $state.go('login').

just use $timeout wrapper:

$timeout(() => {
  $state.go('login')
})

const transition = $timeout(function () {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests