telegraf: Switching from one WizardScene to another causes infinite loop.

Context

If one tries to switch to another wizard from wizard.leave( ctx => { ... } ), it will cause an infinite loop that causes RangeError: Maximum call stack size exceeded.

  • Telegraf.js Version: 3.36.0
  • Node.js Version: v14.15.1
  • Operating System: Windows 10 x64 20H2

Expected Behavior

The ctx.scene.enter( sceneId ) function shouldn’t assume the action of the user and call ctx.scene.leave(). Atleast there should be an option to block this trigger to avoid infinite loop.

Current Behavior

If one tries to switch to another wizard from wizard.leave( ctx => { ... } ), it will cause an infinite loop that causes RangeError: Maximum call stack size exceeded.

Steps to Reproduce

Please provide detailed steps for reproducing the issue.

  1. Enter a specific WizardScene
  2. Simulate moving to another WizardScene when the user leaves the current one ( using the leave callback method )
  3. This should crash the module

Failure Logs

RangeError: Maximum call stack size exceeded

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 23 (4 by maintainers)

Commits related to this issue

Most upvoted comments

If we want to support what you’re trying to do, then this raises a question.

Let’s assume there are three scenes called X, Y, and Z.

  1. User is in X
  2. X has leaveHandler that calls enter(Y)
  3. User requests to go to Z

As Z shall be entered, X will be left. The leaveHandler of X want to switch over to Y, but in fact we are in the middle of switching over to Z. What do you expect to happen now?

How about adding private leaving = false property to SceneContextScene, set it to true while SceneContextScene::leave is running, and don’t call SceneContextScene::leave again if it’s set?

Yap, I was thinking about a 4th parameter too. I’m moving on from this then. Maybe add a warning or something on the documentation to show people not to use this method inside Wizard.leave. There is like a single example around wizards and stage. Thank you @KnorpelSenf and @wojpawlik for the discussion 👍

I do see this need, I just wouldn’t really know how to go about it. Introduce a fourth parameter, so we’d end up with silentLeave and silentEnter? Scenes and Wizards are already difficult to understand, that’s why I’m so hesitant towards adding more configuration in order to prevent infinite recursion. I’d like to have something that—by design—just does not crash, but I cannot come up with something. I’m open for suggestions (explicitly including PRs).

Perhaps silent flag should be dropped in 4.0.0 then? It allows to easily break expectations.

Sure I will do that. But I feel like this was a design problem. Give me a sec