Skip to content

Bad timing routing issue, failing test#16342

Closed
wagenet wants to merge 1 commit into
emberjs:mainfrom
wagenet:bad-timing-routing-issue
Closed

Bad timing routing issue, failing test#16342
wagenet wants to merge 1 commit into
emberjs:mainfrom
wagenet:bad-timing-routing-issue

Conversation

@wagenet

@wagenet wagenet commented Mar 8, 2018

Copy link
Copy Markdown
Member

Not really sure what to name this, or if this test is in the right area,
but it is an issue!


this.add('route:dummy', Route.extend({
redirect() {
return RSVP.resolve()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand well, this is specifically what the test is about ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct.

@wagenet wagenet force-pushed the bad-timing-routing-issue branch from 490042f to 2b206f9 Compare March 8, 2021 22:22
@sly7-7

sly7-7 commented Mar 8, 2021

Copy link
Copy Markdown
Contributor

@wagenet I've updated (locally) this test to highlight the real issue (it needs an expectDeprecation because of the call to this.replaceWith()).
I don't understand what's going on. The only thing I can tell for now, is that adding this Promise.resolve() (so some kind of asynchrony I guess) causes the router to be in a very bad state, ultimately hitting https://github.com/emberjs/ember.js/blob/master/packages/@ember/-internals/routing/lib/system/router.ts#L1750 with an undefined defaultParentState.

'route:dummy',
Route.extend({
redirect() {
return RSVP.resolve().then(() => this.replaceWith('index'));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs something like this:

expectDeprecation(() => {
  this.replaceWith('index');
}, 'Calling replaceWith on a route is deprecated. Use the RouterService instead.');

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

@wagenet wagenet force-pushed the bad-timing-routing-issue branch from 2b206f9 to 1801921 Compare March 8, 2021 22:43
@sly7-7

sly7-7 commented Mar 9, 2021

Copy link
Copy Markdown
Contributor

@rwjblue @wagenet, Could you guys please explain me the difference in term of behavior using return Promise.resolve().then(replaceWith()) and await Promise.resolve(); replaceWith()?

Because for me, they are be the same.

The one from Peter's test (somehow makes the test fail)

this.add(
        'route:dummy',
        Route.extend({
          redirect() {
            return RSVP.resolve().then(() => {
              expectDeprecation(() => {
                this.replaceWith('index');
              }, 'Calling replaceWith on a route is deprecated. Use the RouterService instead.');
            });
          },
        })
      );

The one I just tried (the test is green this way).

this.add(
        'route:dummy',
        Route.extend({
          async redirect() {
            await RSVP.resolve();
            expectDeprecation(() => {
              this.replaceWith('index');
            }, 'Calling replaceWith on a route is deprecated. Use the RouterService instead.');
          },
        })
      );

image

I was thinking maybe await Promise.resolve() would be somehow synchronous, so I modified resolving the Promise after 500ms, and it's working too:
Screenshot from 2021-03-09 08-30-57

@sly7-7

sly7-7 commented Mar 9, 2021

Copy link
Copy Markdown
Contributor

I've made some other tiny experiment around return Promise.resolve().then() / await Promise.resolve().
Maybe this could you give you some clue.

 redirect() {
   return new RSVP.Promise((resolve) => {
     count++;
     // later(resolve, 1); // pass
     // later(resolve, 0); // pass
     // next(resolve); // pass
     // run(resolve); // fails
     // resolve(); // fails
   }).then(() => {
     assert.equal(count, 1);
     expectDeprecation(() => {
       this.replaceWith('index');
     }, 'Calling replaceWith on a route is deprecated. Use the RouterService instead.');
   });
 },

 async redirect() {
   await new RSVP.Promise((resolve) => {
     count++;
     // later(resolve, 1); // pass
     // later(resolve, 0); // pass
     // next(resolve); // pass
     // run(resolve); // pass
     // resolve(); // pass
   });
   assert.equal(count, 1);
   expectDeprecation(() => {
     this.replaceWith('index');
   }, 'Calling replaceWith on a route is deprecated. Use the RouterService instead.');
 },

@wagenet

wagenet commented Mar 9, 2021

Copy link
Copy Markdown
Member Author

Possibly it has to do with the difference in the code generated by the transpiler.

@sly7-7

sly7-7 commented Mar 10, 2021

Copy link
Copy Markdown
Contributor

@wagenet I've had a discussion with @rwjblue on this thing. From the discord chat:
I'm putting that here, so we don't forget:

  • at a high level, we have a somewhat fundamental problem when you return a promise that then redirects

seems related to: emberjs/router.js#310 and emberjs/ember-test-helpers#332

@locks

locks commented Feb 5, 2022

Copy link
Copy Markdown
Contributor

@wagenet is this still relevant?

@wagenet wagenet force-pushed the bad-timing-routing-issue branch from 1801921 to e5564cc Compare February 7, 2022 17:05
@wagenet

wagenet commented Feb 7, 2022

Copy link
Copy Markdown
Member Author

@locks I just rebased. Looks like CI still fails.

@kategengler

Copy link
Copy Markdown
Member

Is this still relevant?

@wagenet wagenet force-pushed the bad-timing-routing-issue branch from e5564cc to fe99bd9 Compare January 10, 2024 22:00
@wagenet

wagenet commented Jan 10, 2024

Copy link
Copy Markdown
Member Author

Rebased again. If this still fails, it's relevant though if we replace the router then it won't be :D

johanrd pushed a commit to johanrd/ember.js that referenced this pull request Mar 8, 2026
Bug originally reported in emberjs#16342 is now resolved.
Application loading state with redirect in dummy route no longer causes timing issues.

Updated Route.extend to class extends Route, this.replaceWith to router service.

Based on PR emberjs#16342.
:
@johanrd

johanrd commented Mar 8, 2026

Copy link
Copy Markdown
Contributor

FWIW: I tried to reproduce by rebasing / adding the test on main, and all tests are green there: johanrd#7

Not sure if it we should rebase properly and actually add the test, or just close the PR.

@kategengler

Copy link
Copy Markdown
Member

Since it passes and we're actively working on replacing the router, I don't think we need to add the test.

Thanks for discovering that info, @johanrd!

@kategengler kategengler closed this Mar 8, 2026
@github-project-automation github-project-automation Bot moved this from Todo to Done in Triaging Mar 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants