BreakPoint.At.Line0
BreakPoint.At.Line0

Reputation: 11

Multiple Context.Forward calls gives exception "execution finished with multiple resume handlers specified through IDialogStack"

I am inside a dialog called as "ParentCustSvcDialog", called from within the "RootDialog". Within this dialog, I am trying to forward the call to LUIS.

Based on what LUIS responds, I am forwarding a call to QnAMaker. I would like to keep this conditional logic within the parent dialog.

However, the conversation does not get through and the call to QnAMaker, and gives exception as below:

Exception: IDialog method execution finished with multiple resume handlers specified through IDialogStack

I pasted the code below. Any idea where is the issue?

ParentCustSvcDialog.cs

    LuisDialogCustomResult luisDialogCustomResult = null;
    QnAMakerDialogCustomResult qnAMakerDialogCustomResult = null;

    private async Task MessageReceived(IDialogContext context, IAwaitable<object> result)
    {
            await context.Forward<LuisDialogCustomResult>(new LuisLeavesDialog(), ResumeAfterLuisDoneDialog, context.Activity.AsMessageActivity());
            if (null == luisDialogCustomResult.MainIntent)  // No meaningful response from LUIS
            {
                // POST to the QnA Maker via the QnA Maker Dialog
                await context.Forward<QnAMakerDialogCustomResult>(new QnAMakerLeavesDialog(), ResumeAfterQnAMakerDoneDialog, context.Activity.AsMessageActivity());
            }
            else    // Meaningful Response from LUIS.
            {   
                await context.PostAsync($"(DEBUG:LUIS) Here is what I found: </br> { customMessage }");
            }

            context.Wait(MessageReceived);
    }

    private async Task ResumeAfterLuisDoneDialog(IDialogContext context, IAwaitable<LuisDialogCustomResult> result)
    {
        // Control Comes to Parent Dialog once done with Luis Portion
        luisDialogCustomResult = (await result as LuisDialogCustomResult);
    }

    private async Task ResumeAfterQnAMakerDoneDialog(IDialogContext context, IAwaitable<QnAMakerDialogCustomResult> result)
    {
        // Control Comes to Parent Dialog once done with QnA Portion
        qnAMakerDialogCustomResult = await result as QnAMakerDialogCustomResult;
    }

Upvotes: 1

Views: 1163

Answers (1)

Alok Rajasukumaran
Alok Rajasukumaran

Reputation: 383

It's very simple. as the exceptions say, when your bot is looking at the code it says multiple ways to go forward through the code.

Your guiding the waterfall to multiple points, which basically means you have an architectural problem. Try to keep up the waterfall model nd keep the bot to exit through only one point at a time.

Bot framework does not like multiple endpoints for the same IDialog.

You can limit it by changing the way you are looking into the problem you are trying to solve.

todo:

  1. Remove multiple exit points for the code.
  2. If you need multiple, Have them differentiated in such a way that only one shows up at a time.
  3. Always make the architecture in such a way that the waterfall model is followed.

Upvotes: 1

Related Questions