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

bot.cancelAllDialogs() called inside a dialog handler causes a crash #1808

Closed
etiennellipse opened this issue Sep 11, 2019 · 5 comments
Closed
Assignees
Labels
Milestone

Comments

@etiennellipse
Copy link
Contributor

I am trying to leave all the existing dialogs from within an handler; checking if the user really wishes to leave, then I call await bot.cancelAllDialogs() in the handler.

I am getting the following error at runtime:

(node:76242) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'state' of undefined
    at BotkitConversation.<anonymous> (/Users/etienne/Code/botkit-example/node_modules/botkit/lib/conversation.js:617:62)
    at Generator.next (<anonymous>)
    at /Users/etienne/Code/botkit-example/node_modules/botkit/lib/conversation.js:7:71
    at new Promise (<anonymous>)
    at __awaiter (/Users/etienne/Code/botkit-example/node_modules/botkit/lib/conversation.js:3:12)
    at BotkitConversation.end (/Users/etienne/Code/botkit-example/node_modules/botkit/lib/conversation.js:614:16)
    at BotkitConversation.<anonymous> (/Users/etienne/Code/botkit-example/node_modules/botkit/lib/conversation.js:558:35)
    at Generator.next (<anonymous>)
    at fulfilled (/Users/etienne/Code/botkit-example/node_modules/botkit/lib/conversation.js:4:58)
    at process._tickCallback (internal/process/next_tick.js:68:7)

After some investigation, I found that the end() method in the BotkitConversation class uses dc.activeDialog which has been nulled by cancelAllDialogs(). Hence, the crash.

Here is the code example for reproduction:

const { BotkitConversation } = require('botkit');

module.exports = function(controller) {
    const DIALOG_SUBJECT_ID = 'subject-dialog';
    const DIALOG_INTERRUPT_ID = 'interrupt';

    const subjectDialog = new BotkitConversation(DIALOG_SUBJECT_ID, controller);

    for (let i = 0; i < 30; i++) {
        subjectDialog.ask(`Message #${i}`, [], `conv-${i}`);
    }

    controller.addDialog(subjectDialog);

    const interruptDialog = new BotkitConversation(DIALOG_INTERRUPT_ID, controller);

    interruptDialog.ask({
        text: "This subject is not interesting to you?",
        quick_replies: [
            {
                title: 'Sure',
                payload: 'Sure'
            },
            {
                title: 'Nope',
                payload: 'Nope'
            }
        ]
    }, [{
        pattern: 'Sure',
        handler: async function (response, convo, bot) {
            await bot.say('Let\'s continue then!');
        },
    },{
        pattern: 'Nope',
        handler: async function (response, convo, bot) {
            await bot.say('Let\'s leave then!');
            await bot.cancelAllDialogs();
        },
    }]);

    controller.addDialog(interruptDialog);

    controller.hears('go', ['message', 'direct_message'], async (bot, message) => {
        await bot.beginDialog(DIALOG_SUBJECT_ID);
    });

    controller.hears('not interested', ['message','direct_message'], async (bot, message) => {
        await bot.beginDialog(DIALOG_INTERRUPT_ID);
    });
};

Context:

  • Botkit version: 4.5.0
  • Messaging Platform: Web
  • Node version: v10.16.3
  • Os: MacOS
@benbrown benbrown self-assigned this Sep 12, 2019
@benbrown benbrown added the bug label Sep 12, 2019
@benbrown benbrown added this to the 4.6 milestone Sep 13, 2019
@chahat-arora
Copy link
Contributor

@etiennellipse hey, did you find any solution or workaround for this?

@etiennellipse etiennellipse changed the title bot.cancelAllDialogs() called inside an handler causes a crash bot.cancelAllDialogs() called inside a dialog handler causes a crash Oct 25, 2019
@etiennellipse
Copy link
Contributor Author

It works from a bot.interrupts handler, though. It would seem that it fails because the handler runs inside a dialog, maybe?

        controller.interrupts(async () => true, ["hello"], async (bot: CerebroBotWorker) => {
            await bot.cancelAllDialogs();
            await bot.say("Hey, you are back! Wanna talk?");
        });

@benbrown
Copy link
Contributor

should be fixed in v4.6

@benbrown benbrown closed this as completed Nov 1, 2019
@chahat-arora
Copy link
Contributor

I don't think it's fixed in v4.6.

@benbrown
Copy link
Contributor

benbrown commented Dec 2, 2019

@chahat-arora can you please send some sample code that exhibits this issue? I am not able to reproduce it.

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

No branches or pull requests

3 participants