【问题标题】:How can I change the default "Sorry, my bot code is having an issue" exception message?如何更改默认的“抱歉,我的机器人代码有问题”异常消息?
【发布时间】:2017-03-23 11:44:34
【问题描述】:

我需要更改默认的“抱歉,我的机器人代码有问题”异常消息。这似乎是一个有点复杂的过程。我已经尝试按照这篇博文中所说的去做:http://wp.sjkp.dk/change-the-sorry-my-bot-code-is-having-an-issue-in-microsoft-bot-framework/

我不了解依赖注入或控制反转,所以这变得相当具有挑战性。我正在使用 Bot Builder 版本 3.5.5。

这是我尝试在我的机器人上使用的博客代码:

PostUnhandledExceptionToUser 类:

using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Dialogs.Internals;
using Microsoft.Bot.Builder.Internals.Fibers;
using Microsoft.Bot.Connector;
using System;
using System.Diagnostics;
using System.Net.Mime;
using System.Resources;
using System.Threading;
using System.Threading.Tasks;

namespace Tiimo.Bot.BotFramework
{
    public class PostUnhandledExceptionToUser : IPostToBot
    {
        private readonly ResourceManager resources;
        private readonly IPostToBot inner;
        private readonly IBotToUser botToUser;
        private readonly TraceListener trace;

        public PostUnhandledExceptionToUser(IPostToBot inner, IBotToUser botToUser, ResourceManager resources, TraceListener trace)
        {
            SetField.NotNull(out this.inner, nameof(inner), inner);
            SetField.NotNull(out this.botToUser, nameof(botToUser), botToUser);
            SetField.NotNull(out this.resources, nameof(resources), resources);
            SetField.NotNull(out this.trace, nameof(trace), trace);
        }

        async Task IPostToBot.PostAsync(IActivity activity, CancellationToken token)
        {
            try
            {
                await this.inner.PostAsync(activity, token);
            }
            catch (Exception error)
            {
                try
                {
                    if (Debugger.IsAttached)
                    {
                        var message = this.botToUser.MakeMessage();
                        message.Text = $"Exception: { error.Message}";
                        message.Attachments = new[]
                        {
                            new Attachment(contentType: MediaTypeNames.Text.Plain, content: error.StackTrace)
                        };

                        await this.botToUser.PostAsync(message);
                    }
                    else
                    {
                        await this.botToUser.PostAsync("My Personal Error Message");
                    }
                }
                catch (Exception inner)
                {
                    this.trace.WriteLine(inner);
                }

                throw;
            }
        }
    }
}

DefaultExceptionMessageOverrideModule 类:

using Autofac;
using Autofac.Builder;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Dialogs.Internals;
using Microsoft.Bot.Builder.History;
using Microsoft.Bot.Builder.Internals.Fibers;
using Microsoft.Bot.Builder.Scorables.Internals;
using Microsoft.Bot.Connector;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Resources;
using System.Web;


namespace Tiimo.Bot.BotFramework
{
    public class DefaultExceptionMessageOverrideModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterType<PostUnhandledExceptionToUser>().Keyed<IPostToBot>(typeof(PostUnhandledExceptionToUser)).InstancePerLifetimeScope();


            RegisterAdapterChain<IPostToBot>(builder, 
                typeof(PersistentDialogTask),
                typeof(ExceptionTranslationDialogTask),
                typeof(SerializeByConversation),
                typeof(SetAmbientThreadCulture),
                typeof(PostUnhandledExceptionToUser),
                typeof(LogPostToBot)
            )
            .InstancePerLifetimeScope();
        }

        public static IRegistrationBuilder<TLimit, SimpleActivatorData, SingleRegistrationStyle> RegisterAdapterChain<TLimit>(ContainerBuilder builder, params Type[] types)
        {
            return
                builder
                .Register(c =>
                {
                // http://stackoverflow.com/questions/23406641/how-to-mix-decorators-in-autofac
                TLimit service = default(TLimit);
                    for (int index = 0; index < types.Length; ++index)
                    {
                    // resolve the keyed adapter, passing the previous service as the inner parameter
                    service = c.ResolveKeyed<TLimit>(types[index], TypedParameter.From(service));
                    }

                    return service;
                })
                .As<TLimit>();
        }
    }  
}

创建这些类后,我转到 Global.asax 文件并输入以下代码:

var builder = new ContainerBuilder();
builder.RegisterModule(new DefaultExceptionMessageOverrideModule());
builder.Update(Conversation.Container);

它构建成功,但是当我向机器人发送消息时,我收到以下错误:

调用构造函数“Void .ctor(Microsoft.Bot.Builder.Dialogs.Internals.IPostToBot, Microsoft.Bot.Builder.Dialogs.Internals.IBotData)’ 类型 “持久对话任务”。 —> Valor não pode ser nulo。名称做参数: 内部(有关详细信息,请参阅内部异常。)

我猜它翻译成类似的东西

调用构造函数“Void”时抛出异常 .ctor(Microsoft.Bot.Builder.Dialogs.Internals.IPostToBot, Microsoft.Bot.Builder.Dialogs.Internals.IBotData)’ 类型 “持久对话任务”。 —> 值不能为空。参数名称:内 (有关详细信息,请参阅内部异常。)

代码有问题吗?我究竟做错了什么?有没有其他方法可以做到这一点?

【问题讨论】:

标签: c# botframework


【解决方案1】:

尝试使用此代码注册适配器链:

builder
        .RegisterAdapterChain<IPostToBot>
        (
            typeof(EventLoopDialogTask),
            typeof(SetAmbientThreadCulture),
            typeof(PersistentDialogTask),
            typeof(ExceptionTranslationDialogTask),
            typeof(SerializeByConversation),
            typeof(PostUnhandledExceptionToUser),
            typeof(LogPostToBot)
        )
        .InstancePerLifetimeScope();

我相信在某个时候PersistentDialogTask 已更新,而they added a dependency on an IPostToBot implementation 在您使用的注册中未提供。我从DialogModule获取了更新的代码。

如果您查看代码,您会发现EventLoopDialogTask 是链中的第一项,它不依赖于任何IPostToBot 实现。我的猜测是,在您阅读帖子时,PersisteDialogTask 是该链中的第一项。

【讨论】:

  • 它现在工作得很好!我花了太多时间试图做到这一点,所以非常感谢。 :)
  • 这如何解决您的问题?其中哪一种类型解决了这个问题?
  • 公平的问题。我相信问题是适配器链在某个时候发生了变化,现在 PersistentDialogTask 依赖于 IPostToBot 实现(参见code,没有提供他使用的注册。我用这些细节更新了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-28
  • 1970-01-01
  • 2017-03-09
  • 2016-02-11
相关资源
最近更新 更多