Botframework 如何捕获从FormFlow对话框抛出的异常?

Botframework 如何捕获从FormFlow对话框抛出的异常?,botframework,bots,Botframework,Bots,我使用FormFlow技术编写了一个机器人对话框 下面是构建对话框的BuildForm方法 public static IForm<CarValuationDialog> BuildForm() { var builder = new FormBuilder<CarValuationDialog>(); Configure(builder); return new FormBuilder<CarValuationDialog>()

我使用FormFlow技术编写了一个机器人对话框

下面是构建对话框的
BuildForm
方法

public static IForm<CarValuationDialog> BuildForm()
{
    var builder = new FormBuilder<CarValuationDialog>();

    Configure(builder);

    return new FormBuilder<CarValuationDialog>()
        .Field(nameof(ValuationOption))
        .Field(nameof(RegistrationNumber))
        .Field(nameof(Mileage))
        .Field(
            nameof(PreviousOwnerOption),
            active: carValuation => carValuation.ValuationOption == ValuationOptions.LookingToSell)
        .Field(
            nameof(ServiceHistoryOption),
            active: carValuation => carValuation.ValuationOption == ValuationOptions.LookingToSell)
        .OnCompletion(GetValuationAndDisplaySummaryToUser)
        .Confirm(Confirmation)
        .Build();
}
但是没有执行任何异常处理程序

有人能给我指一下正确的方向吗?

试试这个-

消息控制器

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
    if (activity.Type == ActivityTypes.Message)
    {
        await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
    }
    else
    {
        HandleSystemMessage(activity);
    }
    var response = Request.CreateResponse(HttpStatusCode.OK);
    return response;
}
公共异步任务发布([FromBody]活动)
{
if(activity.Type==ActivityTypes.Message)
{
wait Conversation.sendaync(活动,()=>newdialogs.RootDialog());
}
其他的
{
HandleSystemMessage(活动);
}
var response=Request.CreateResponse(HttpStatusCode.OK);
返回响应;
}
并添加一个新的类根对话框:

根目录对话框

public Task StartAsync(IDialogContext context)
{
    context.Wait(MessageReceivedAsync);

    return Task.CompletedTask;
}

private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
    var message = await result;
    FormDialog<CustomerDetails> customerForm = new FormDialog<CustomerDetails>(new CustomerDetails(), CustomerDetails.BuildForm, FormOptions.PromptInStart);
    context.Call(customerForm, FormSubmitted);
}

public async Task FormSubmitted(IDialogContext context, IAwaitable<CustomerDetails> result)
{
    try
    {
        var form = await result;
        await context.PostAsync("Thanks for your response.");
    }
    catch (FormCanceledException<SoftwareRequest> e)
    {
        string reply;
        if (e.InnerException == null)
        {
            reply = $"Thanks for filling out the form.";

        }
        else
        {
            reply = $"Sorry, I've had a short circuit.  Please try again.";
        }
        context.Done(true);
        await context.PostAsync(reply);
    }
}
公共任务StartSync(IDialogContext上下文)
{
Wait(MessageReceivedAsync);
返回Task.CompletedTask;
}
专用异步任务消息ReceivedAsync(IDialogContext上下文,IAwaitable结果)
{
var消息=等待结果;
FormDialog CustomPerform=新建FormDialog(新建CustomerDetails(),CustomerDetails.BuildForm,FormOptions.PrompInstart);
调用(customerForm、FormSubmitted);
}
已提交公共异步任务表单(IDialogContext上下文,IAwaitable结果)
{
尝试
{
var form=等待结果;
等待上下文。PostAsync(“感谢您的回复”);
}
捕获(FormCanceledException e)
{
字符串回复;
if(e.InnerException==null)
{
答复=$“感谢您填写表格。”;
}
其他的
{
reply=$“对不起,我短路了。请再试一次。”;
}
上下文。完成(true);
等待上下文。PostAsync(回复);
}
}
注意


请将CustomerDetails更改为表单类的名称。

谢谢您的帮助,这对我很有用。在
catch
块中,我考虑调用
context.Reset()
,以便从第一步开始启动bot。这样做对吗?我怎样才能从catch块重新启动bot?从第一步开始是什么意思?您想开始对话,好像什么都没发生,或者您想重新填写表单。。使用context.Reset可能会为您提供堆栈空异常say,例如,用户输入了注册号和里程值。机器人接受这些输入以搜索车辆,但未找到车辆数据。我需要告诉用户没有归还任何车辆,并以某种方式让他们回到要求他们输入注册号的问题。请问这样做可能吗?
public Task StartAsync(IDialogContext context)
{
    context.Wait(MessageReceivedAsync);

    return Task.CompletedTask;
}

private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
    var message = await result;
    FormDialog<CustomerDetails> customerForm = new FormDialog<CustomerDetails>(new CustomerDetails(), CustomerDetails.BuildForm, FormOptions.PromptInStart);
    context.Call(customerForm, FormSubmitted);
}

public async Task FormSubmitted(IDialogContext context, IAwaitable<CustomerDetails> result)
{
    try
    {
        var form = await result;
        await context.PostAsync("Thanks for your response.");
    }
    catch (FormCanceledException<SoftwareRequest> e)
    {
        string reply;
        if (e.InnerException == null)
        {
            reply = $"Thanks for filling out the form.";

        }
        else
        {
            reply = $"Sorry, I've had a short circuit.  Please try again.";
        }
        context.Done(true);
        await context.PostAsync(reply);
    }
}