编程语言
首页 > 编程语言> > c#-Bot Framework v4.2-从OnTurnError异常轻松恢复

c#-Bot Framework v4.2-从OnTurnError异常轻松恢复

作者:互联网

我一直在阅读文档,并在代码示例中寻找提示和灵感,到目前为止,我还没有发现任何东西.

如果我们在漫游器中捕获到全局异常,则输入OnTurnError处理程序:

// Catches any errors that occur during a conversation turn and logs them.
options.OnTurnError = async (context, exception) =>
{
    logger.LogError($"Exception caught : {exception}");
    await context.SendActivityAsync("Sorry, it looks like something went wrong.");
};

我没有在文档中或任何讨论中找到任何东西,任何人随后都可以从错误中恢复并重新开始对话.我有一个有效的解决方案,但我想知道是否缺少一种“最佳实践”方法.我现在正在这样做:

options.OnTurnError = async (context, exception) =>
{
    logger.LogError($"Exception caught : {exception}");
    await context.SendActivityAsync("Sorry, it looks like something went wrong.");

    await _conversationState.DeleteAsync(context);

    await MyBot.SendIntroCardAsync(context, CancellationToken.None);
};

如果没有这种恢复,我们将使用户陷入僵局.我找不到更好的解决方案吗?

解决方法:

“抹去”对话状态并重新开始当然是处理它的一种方法,尽管有些繁重.不过,调用DeleteAsync是正确的方法.也许认为您不想擦除所有对话状态,而只是擦除DialogState?您可以通过仅调用IStatePropertyAccessor< DialogState> :: DeleteAsync来实现.一切都取决于您所保持的状态以及状态.

现在,我看到的问题是尝试从OnTurnError处理程序触发您的机器人,以便在发生这种情况时立即重新启动对话.看来您正在调用静态方法(SendIntroCardAsync),我认为它可以工作,但它创建的耦合非常紧密,使我感到不舒服.

我的一部分希望建议,如果您的MyBot确实希望参与这种级别的异常处理,则可以将实际的try / catch放入机器人本身的OnTurnAsync中,从而基本上将活动方块的处理保持在责任域,并且能够干净地包含并触发SendIntroCardAsync.然后,在这种情况下,除非机器人未能正确处理异常,否则可能永远不会触发OnTurnError.除了对SendIntroCardAsync的调用之外,我仍然将所有内容保留在该处理程序逻辑中,但是现在您知道,只有在bot无法正确处理异常(应该是极少见的)或部分错误的情况下,才会触发该事件.上游中间件引发异常.我也不是很喜欢这件事,因为它给机器人赋予了一种责任,否则它可能是不可知的.

我认为,考虑到这一点,我可能会采用的最终方法是构建特定的中间件,并将其安装在执行顶级异常处理的管道的“顶部”,而不是确切知道要调用什么一旦完成了该处理,它实际上将再次重新执行整个管道一些可配置的次数.这样,从顶级异常处理的角度来看,您的下游中间件和bot仍然是“哑巴”,但是您仍然可以通过在注册时使用此中间件配置回调来选择要做什么(在这种情况下,擦除某些状态),并且最终,一旦将异常作为新的请求处理,您的机器人就会看到回合的重播.该中间件甚至可以在ITurnContext :: TurnState包中添加一些内容,以使下游逻辑能够检测到它处于重播状态并且行为略有不同.例如,假设您的机器人能够做到这一点:

public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
   if(turnContext.IsReplayingTurnBecauseOfException())
   {
       ... send sorry msg and restart dialogs from wherever you want ...
   }
}

IsReplayingTurnBecauseOfException(进行辩论)是ITurnContext的扩展方法,它将与新的中间件一起提供,以直接读取TurnState详细信息来抽象代码.就像是:

public static bool IsReplayingTurnBecauseOfException(this ITurnContext turnContext) =>
    turnContext.TurnState.ContainsKey("MySuperAwesomeExceptionHandlingMiddleware.IsReplayingBecauseOfException");

标签:botframework,error-handling,c,net
来源: https://codeday.me/bug/20191211/2106373.html