正如标题所述,我正在寻找一种方法,该方法可以从Virtual Assistant模板的DefaultAdapter类内提供的dialogContext.EndDialogAsync()
方法内部调用dialogContext.CancelAllDialogsAsync()
或OnTurnError
。
我已经读过this documentation,但这全是关于在正常事件流中管理对话框,而不是在错误状态下对其进行处理。
我已经更新了DefaultAdapter类的构造函数,以添加到UserState
,ConversationState
和DynamicWaterfallState
中,并且正在调用相关方法来清除状态。不幸的是,即使在清除状态后,引发错误的对话框仍然处于活动状态,因此用户仍然可以单击卡片上的按钮-对话框结束后,可以单击按钮,但回发似乎没有触发。
当前代码:
public DefaultAdapter(
BotSettings settings,
ICredentialProvider credentialProvider,
IBotTelemetryClient telemetryClient,
BotStateSet botStateSet,
UserState userState,
ConversationState conversationState,
DynamicWaterfallState dynamicWaterfallState
)
: base(credentialProvider)
{
OnTurnError = async (turnContext, exception) =>
{
await turnContext.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"{exception.Message}"));
await turnContext.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"{exception.StackTrace}"));
await turnContext.SendActivityAsync(MainStrings.ERROR);
telemetryClient.TrackException(exception);
// Nuke the state
botStateSet.BotStates.Clear();
await botStateSet.SaveAllChangesAsync(turnContext, true);
await userState.ClearStateAsync(turnContext);
await userState.SaveChangesAsync(turnContext, true);
await conversationState.ClearStateAsync(turnContext);
await conversationState.SaveChangesAsync(turnContext);
dynamicWaterfallState.ClearState();
};
Use(new TranscriptLoggerMiddleware(new AzureBlobTranscriptStore(settings.BlobStorage.ConnectionString, settings.BlobStorage.Container)));
Use(new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true));
Use(new ShowTypingMiddleware());
Use(new SetLocaleMiddleware(settings.DefaultLocale ?? "en-us"));
Use(new EventDebuggerMiddleware());
Use(new AutoSaveStateMiddleware(botStateSet));
}
我正在寻找一种通用的方法,而不是将我的所有代码都包装在try-catch语句的对话框中。
DialogContext
被Bot框架实例化的当前方式意味着它不会导致依赖注入,因为它依赖于运行时值,如下所示:
// In DialogBot.cs constructor
var dialogState = conversationState.CreateProperty<DialogState>(nameof(VirtualAssistant));
_dialogs = new DialogSet(dialogState);
_dialogs.Add(dialog);
// In DialogBot.cs OnTurnAsync
var dc = await _dialogs.CreateContextAsync(turnContext);
我在写这篇文章时只是想了一下...我可以包装OnTurnAsync
的内容,我仍然可以在一个地方来管理错误处理,但是无法使用似乎很可惜适配器模式只是因为我正在使用对话框。