1
votes

Hi i have this code that prompt the user for their location. I am using Botframework v4 and C#. I put the messenger quick reply in an attachment prompt.

  if (response == "test location")
        {
            Activity reply = stepContext.Context.Activity.CreateReply();

            reply.ChannelData = JObject.FromObject(
            new
            {
                text = "loc",
                quick_replies = new object[]
                {
                    new
                    {
                        content_type = "location",
                    },
                },
            });

            return await stepContext.PromptAsync(
               ATTACHPROMPT,
               new PromptOptions
               {
                   Prompt = reply,
               });
        }

But after the user send its location. The bot crashes. How can i handle the return of the location so the bot won't crash? Here is the exeption

System.ArgumentNullException: Value cannot be null. Parameter name: utterance at Microsoft.Bot.Builder.AI.Luis.LuisRecognizer.d*23.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.AI.Luis.LuisRecognizer.d*10.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.BotBuilderSamples.BasicBot.d*24.MoveNext() in C:\Users\bguevarra\Desktop\finko\FinkoBot\Bots\BasicBot.cs:line 104 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.MiddlewareSet.d*3.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.BotAdapter.d__13.MoveNext() == Oops Sorry, it looks like something went wrong.

OnTurnAsync()

    public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken)
    {
        var dc = await _dialogs.CreateContextAsync(turnContext, cancellationToken);
        var activity = turnContext.Activity;

        var userstate = await _basicAccessors.BasicUserStateAccessor.GetAsync(turnContext, () => new BasicUserState(), cancellationToken);
        var state = await _basicAccessors.BasicStateAccessor.GetAsync(turnContext, () => new BasicState(), cancellationToken);

        if (turnContext.Activity.Type == ActivityTypes.Message)
        {
            turnContext.TurnState.Add("BasicAccessors", _basicAccessors);

            string text = string.IsNullOrEmpty(turnContext.Activity.Text) ? string.Empty : turnContext.Activity.Text.ToLower();

            var luisResults = await _services.LuisServices[LuisConfiguration].RecognizeAsync(dc.Context, cancellationToken);
            var topScoringIntent = luisResults?.GetTopScoringIntent();
            var topIntent = topScoringIntent.Value.intent;
            turnContext.TurnState.Add("topIntent", topIntent);

            turnContext.TurnState.Add("text", text);

            var interrupted = await IsTurnInterruptedAsync(turnContext);
            if (interrupted)
            {
                await _basicAccessors.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
                await _basicAccessors.UserState.SaveChangesAsync(turnContext, false, cancellationToken);
                return;
            }

            // Continue the current dialog
            var dialogResult = await dc.ContinueDialogAsync();

            // if no one has responded,
            if (!dc.Context.Responded)
            {
                // examine results from active dialog
                switch (dialogResult.Status)
                {
                    case DialogTurnStatus.Empty:

                        switch (topIntent) 
                        {
                            case MainDialogIntent:
                                await dc.BeginDialogAsync(MainDialogId);
                                break;

                            case LoanCalculatorIntent:
                                await dc.BeginDialogAsync(LoanCalculatorId);
                                break;

                            case RealEstateIntent:
                                await dc.BeginDialogAsync(RealEstateDialogId);
                                break;

                            case GreetingIntent:
                                Random rnd = new Random();
                                int x = rnd.Next(1, 5);
                                switch (x)
                                {
                                    case 1:
                                        await dc.Context.SendActivityAsync("Hi!");
                                        break;

                                    case 2:
                                        await dc.Context.SendActivityAsync("Hello!");
                                        break;

                                    case 3:
                                        await dc.Context.SendActivityAsync("Good day!");
                                        break;

                                    default:
                                        break;
                                }

                                break;

                            case NoneIntent: // NoneIntent:
                            default:
                                await dc.Context.SendActivityAsync("I didn't understand what you just said to me.");
                                break;
                        }

                        break;

                    case DialogTurnStatus.Waiting:
                        // The active dialog is waiting for a response from the user, so do nothing.
                        break;

                    case DialogTurnStatus.Complete:
                        await dc.EndDialogAsync();
                        break;

                    default:
                        await dc.CancelAllDialogsAsync();
                        break;
                }
            }

            await _basicAccessors.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
            await _basicAccessors.UserState.SaveChangesAsync(turnContext, false, cancellationToken);
        }
        else if (activity.Type == ActivityTypes.ConversationUpdate)
        {
            if (activity.MembersAdded != null)
            {
                // Iterate over all new members added to the conversation.
                foreach (var member in activity.MembersAdded)
                {
                    // Greet anyone that was not the target (recipient) of this message.
                    // To learn more about Adaptive Cards, see https://aka.ms/msbot-adaptivecards for more details.
                    if (member.Id != activity.Recipient.Id)
                    {
                        await SendWelcomeMessageAsync(turnContext, cancellationToken);
                    }
                }
            }
        }

        await _basicAccessors.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
        await _basicAccessors.UserState.SaveChangesAsync(turnContext, false, cancellationToken);
    }
1
Can you add your OnTurnAsync method? You most likely need to check if the incoming activity's text value is not null before passing it to the LUIS recognizer. When the user clicks on the location quick reply in Facebook Messenger, the incoming activity does not add text property which would cause a 'Value cannot be null' error when calling LUIS.tdurnford
I've added the OnTurnAsync sir. Also sir in what prompt should i put location quick reply? It is triggering the RetryPrompt in TextPrompt and AttachmentPrompt.user10860402
In regards to your follow up question, I would use a TextPrompt, but you have to use a custom validator function since the default is expecting a text value which is null in the incoming activity. I believe I went into more detail on one of your other StackOverflow Questions.tdurnford
Did checking if the value is null or empty not resolve the error? If it is null, I would recommend just skipping the LUIS call instead of passing it an empty string.tdurnford
@tdurnford Thank you so much sir tdurnford! I will check later when i get a pc and accept your answer.user10860402

1 Answers

1
votes

When the user clicks on the location quick reply in Facebook Messenger, the incoming activity does not have a text property which would cause a 'Value cannot be null' error when calling LUIS. This is currently a known issue in the BotFramework, and the development team is currently working to resolve this problem. In the meantime, check to make sure the incoming activity's text attribute is not null or empty before calling the LUIS recognizer.

if(!string.IsNullOrEmpty(turnContext.Activity.Text)) {
  var luisResults = await _services.LuisServices[LuisConfiguration].RecognizeAsync(dc.Context, cancellationToken);
} 

Hope this helps!