C# | MS BotBuilder | Usage of DefaultIfException

338 views Asked by At

I am trying to track down some documentation on how to use DefaultIfException in the MS Bot builder SDK. There are no docs on its usage as far as I can see.

We're trying to avoid the 'sorry my bot code is having an issue' message being posted to the user. Using DefaultIfException does what it says and 'stops the propagation of the exception', but then I'm not sure how to post my own error message, instead of just nothing.

It would be great if we had a way to tell the bot framework to use a custom error dialog class or something similar.

EDIT for code samples: await Conversation.SendAsync(activity, () => new RootDialog().DefaultIfException()); Where RootDialog() is a custom dialog class of ours which simply implements IDialog<object>

You'll notice if you implement IDialog<object> that you get access to public async Task StartAsync(IDialogContext context). In this method we call context.Wait(MessageReceivedAsync);, which then has this: public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)

In this method we handle processing the message, and wrap the processing in a try-catch where we then handle the error.

To be clear - we're not actually using the DefaultIfException, as it doesn't allow us to use our own error message. But you could use just DefaulIfException if you just wanted to stop the error propagation

1

There are 1 answers

0
Will Portnoy On BEST ANSWER

I'd modify the code from DefaultIfExceptionDialog as follows:

[Serializable]
public sealed class ErrorMessageDialog<T, E> : IDialog<T> where E : Exception
{
    public readonly IDialog<T> Antecedent;
    public ErrorMessageDialog(IDialog<T> antecedent)
    {
        SetField.NotNull(out this.Antecedent, nameof(antecedent), antecedent);
    }
    async Task IDialog<T>.StartAsync(IDialogContext context)
    {
        context.Call<T>(this.Antecedent, ResumeAsync);
    }
    private async Task ResumeAsync(IDialogContext context, IAwaitable<T> result)
    {
        try
        {
            context.Done(await result);
        }
        catch (E)
        {
            await context.PostAsync("sorry");
            context.Done(default(T));
        }
    }