如何更改默认的 "Sorry, my bot code is having an issue" 异常消息?
How can I change the default "Sorry, my bot code is having an issue" exception message?
我需要更改默认的 "Sorry, my bot code is having an issue" 异常消息。看起来这是一个有点复杂的过程。我已尝试按照此博客 post 中的说明进行操作:http://wp.sjkp.dk/change-the-sorry-my-bot-code-is-having-an-issue-in-microsoft-bot-framework/
我不了解依赖注入或控制反转,所以这成为一个相当大的挑战。我使用的是 Bot Builder 版本 3.5.5。
这是我尝试在我的机器人上使用的博客代码:
PostUnhandledExceptionToUser class:
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 class:
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 =>
{
//
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>();
}
}
}
创建这些 classes 后,我转到 Global.asax 文件并输入以下代码:
var builder = new ContainerBuilder();
builder.RegisterModule(new DefaultExceptionMessageOverrideModule());
builder.Update(Conversation.Container);
构建成功,但是当我向机器人发送消息时出现以下错误:
An exception was thrown while invoking the constructor ‘Void .ctor(Microsoft.Bot.Builder.Dialogs.Internals.IPostToBot,
Microsoft.Bot.Builder.Dialogs.Internals.IBotData)’ on type
‘PersistentDialogTask’. —> Valor não pode ser nulo. Nome do parâmetro:
inner (See inner exception for details.)
我猜它翻译成类似
的东西
An exception was thrown while invoking the constructor ‘Void
.ctor(Microsoft.Bot.Builder.Dialogs.Internals.IPostToBot,
Microsoft.Bot.Builder.Dialogs.Internals.IBotData)’ on type
‘PersistentDialogTask’. —> Value cannot be null. Parameter name: inner
(See inner exception for details.)
代码有问题吗?我究竟做错了什么?还有其他方法吗?
尝试使用此代码注册适配器链:
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 which, in the registration you were using, was not being provided. I took the updated code from the DialogModule。
如果您查看代码,您会发现 EventLoopDialogTask
是链中的第一项,它不依赖于任何 IPostToBot
实现。我的猜测是,在您阅读 post 时,PersisteDialogTask
是该链中的第一项。
我需要更改默认的 "Sorry, my bot code is having an issue" 异常消息。看起来这是一个有点复杂的过程。我已尝试按照此博客 post 中的说明进行操作:http://wp.sjkp.dk/change-the-sorry-my-bot-code-is-having-an-issue-in-microsoft-bot-framework/
我不了解依赖注入或控制反转,所以这成为一个相当大的挑战。我使用的是 Bot Builder 版本 3.5.5。
这是我尝试在我的机器人上使用的博客代码:
PostUnhandledExceptionToUser class:
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 class:
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 =>
{
//
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>();
}
}
}
创建这些 classes 后,我转到 Global.asax 文件并输入以下代码:
var builder = new ContainerBuilder();
builder.RegisterModule(new DefaultExceptionMessageOverrideModule());
builder.Update(Conversation.Container);
构建成功,但是当我向机器人发送消息时出现以下错误:
An exception was thrown while invoking the constructor ‘Void .ctor(Microsoft.Bot.Builder.Dialogs.Internals.IPostToBot, Microsoft.Bot.Builder.Dialogs.Internals.IBotData)’ on type ‘PersistentDialogTask’. —> Valor não pode ser nulo. Nome do parâmetro: inner (See inner exception for details.)
我猜它翻译成类似
的东西An exception was thrown while invoking the constructor ‘Void .ctor(Microsoft.Bot.Builder.Dialogs.Internals.IPostToBot, Microsoft.Bot.Builder.Dialogs.Internals.IBotData)’ on type ‘PersistentDialogTask’. —> Value cannot be null. Parameter name: inner (See inner exception for details.)
代码有问题吗?我究竟做错了什么?还有其他方法吗?
尝试使用此代码注册适配器链:
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 which, in the registration you were using, was not being provided. I took the updated code from the DialogModule。
如果您查看代码,您会发现 EventLoopDialogTask
是链中的第一项,它不依赖于任何 IPostToBot
实现。我的猜测是,在您阅读 post 时,PersisteDialogTask
是该链中的第一项。