From 4de30e9ed641b1cf250e1dab20a6088c9def8dfa Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Tue, 11 Jan 2022 15:40:47 +0800 Subject: [PATCH] feat(tasks): add job execute exception handler --- .../components/BackgroundJobInfoTable.vue | 4 + .../LINGYUN.MicroService.TaskManagement.sln | 7 ++ .../BackgroundTasks/IJobExceptionNotifier.cs | 9 +++ .../JobExceptionNotificationContext.cs | 16 ++++ .../JobRunnableContextExtensions.cs | 2 +- .../NullJobExceptionNotifier.cs | 14 ++++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++++++++ ...p.BackgroundTasks.ExceptionHandling.csproj | 21 +++++ ...pBackgroundTasksExceptionHandlingModule.cs | 10 +++ .../ExceptionHandling/JobExceptionNotifier.cs | 76 +++++++++++++++++++ .../FodyWeavers.xml | 4 +- .../Abp/BackgroundTasks/Jobs/SendEmailJob.cs | 58 +++++++++++++- .../Internal/JobExecutedEvent.cs | 20 ++++- ...Service.TaskManagement.HttpApi.Host.csproj | 1 + .../TaskManagementHttpApiHostModule.cs | 2 + 16 files changed, 269 insertions(+), 8 deletions(-) create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobExceptionNotifier.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobExceptionNotificationContext.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/NullJobExceptionNotifier.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/FodyWeavers.xml create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/FodyWeavers.xsd create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN.Abp.BackgroundTasks.ExceptionHandling.csproj create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/AbpBackgroundTasksExceptionHandlingModule.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/JobExceptionNotifier.cs diff --git a/apps/vue/src/views/task-management/background-jobs/components/BackgroundJobInfoTable.vue b/apps/vue/src/views/task-management/background-jobs/components/BackgroundJobInfoTable.vue index 273d7be35..fa909c686 100644 --- a/apps/vue/src/views/task-management/background-jobs/components/BackgroundJobInfoTable.vue +++ b/apps/vue/src/views/task-management/background-jobs/components/BackgroundJobInfoTable.vue @@ -131,24 +131,28 @@ function handlePause(record) { pause(record.id).then(() => { message.success(L('Successful')); + reload(); }); } function handleResume(record) { resume(record.id).then(() => { message.success(L('Successful')); + reload(); }); } function handleTrigger(record) { trigger(record.id).then(() => { message.success(L('Successful')); + reload(); }); } function handleStop(record) { stop(record.id).then(() => { message.success(L('Successful')); + reload(); }); } diff --git a/aspnet-core/LINGYUN.MicroService.TaskManagement.sln b/aspnet-core/LINGYUN.MicroService.TaskManagement.sln index b8077447a..f06899be8 100644 --- a/aspnet-core/LINGYUN.MicroService.TaskManagement.sln +++ b/aspnet-core/LINGYUN.MicroService.TaskManagement.sln @@ -38,6 +38,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.BackgroundTasks EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.BackgroundTasks.Jobs", "modules\task-management\LINGYUN.Abp.BackgroundTasks.Jobs\LINGYUN.Abp.BackgroundTasks.Jobs.csproj", "{4C59F590-AA6C-4C46-8060-DA65D8305980}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.BackgroundTasks.ExceptionHandling", "modules\task-management\LINGYUN.Abp.BackgroundTasks.ExceptionHandling\LINGYUN.Abp.BackgroundTasks.ExceptionHandling.csproj", "{8507BBFA-FE56-4426-BBFA-C92906CB8407}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -88,6 +90,10 @@ Global {4C59F590-AA6C-4C46-8060-DA65D8305980}.Debug|Any CPU.Build.0 = Debug|Any CPU {4C59F590-AA6C-4C46-8060-DA65D8305980}.Release|Any CPU.ActiveCfg = Release|Any CPU {4C59F590-AA6C-4C46-8060-DA65D8305980}.Release|Any CPU.Build.0 = Release|Any CPU + {8507BBFA-FE56-4426-BBFA-C92906CB8407}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8507BBFA-FE56-4426-BBFA-C92906CB8407}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8507BBFA-FE56-4426-BBFA-C92906CB8407}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8507BBFA-FE56-4426-BBFA-C92906CB8407}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -104,6 +110,7 @@ Global {E8022994-A19F-4540-B9D1-7EF4AA85D18A} = {8DA8A2EE-0B26-487E-A6C4-518906E92B1B} {4A049C32-55F2-4A5F-954A-C8A977C2D87F} = {C38EB7EF-BAE9-4129-862A-71C652B81775} {4C59F590-AA6C-4C46-8060-DA65D8305980} = {C38EB7EF-BAE9-4129-862A-71C652B81775} + {8507BBFA-FE56-4426-BBFA-C92906CB8407} = {C38EB7EF-BAE9-4129-862A-71C652B81775} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E1FD1F4C-D344-408B-97CF-B6F1F6D7D293} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobExceptionNotifier.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobExceptionNotifier.cs new file mode 100644 index 000000000..262685cb9 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobExceptionNotifier.cs @@ -0,0 +1,9 @@ +using JetBrains.Annotations; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.BackgroundTasks; + +public interface IJobExceptionNotifier +{ + Task NotifyAsync([NotNull] JobExceptionNotificationContext context); +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobExceptionNotificationContext.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobExceptionNotificationContext.cs new file mode 100644 index 000000000..046978690 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobExceptionNotificationContext.cs @@ -0,0 +1,16 @@ +using System; + +namespace LINGYUN.Abp.BackgroundTasks; + +public class JobExceptionNotificationContext +{ + public JobInfo JobInfo { get; } + public Exception Exception { get; } + public JobExceptionNotificationContext( + JobInfo jobInfo, + Exception exception) + { + JobInfo = jobInfo; + Exception = exception; + } +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobRunnableContextExtensions.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobRunnableContextExtensions.cs index f2fe7510b..c87d46bc5 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobRunnableContextExtensions.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobRunnableContextExtensions.cs @@ -71,7 +71,7 @@ public static class JobRunnableContextExtensions { return value; } - throw new ArgumentException(key + " not specified."); + throw new ArgumentException($"Job required data {key} not specified."); } public static bool TryGetJobData(this JobRunnableContext context, string key, out object value) diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/NullJobExceptionNotifier.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/NullJobExceptionNotifier.cs new file mode 100644 index 000000000..8cc0e6e0e --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/NullJobExceptionNotifier.cs @@ -0,0 +1,14 @@ +using JetBrains.Annotations; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.BackgroundTasks; + +[Dependency(TryRegister = true)] +public class NullJobExceptionNotifier : IJobExceptionNotifier, ISingletonDependency +{ + public Task NotifyAsync([NotNull] JobExceptionNotificationContext context) + { + return Task.CompletedTask; + } +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/FodyWeavers.xml b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/FodyWeavers.xsd b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN.Abp.BackgroundTasks.ExceptionHandling.csproj b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN.Abp.BackgroundTasks.ExceptionHandling.csproj new file mode 100644 index 000000000..08e166f0c --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN.Abp.BackgroundTasks.ExceptionHandling.csproj @@ -0,0 +1,21 @@ + + + + + + + net6.0 + + + + + + + + + + + + + + diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/AbpBackgroundTasksExceptionHandlingModule.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/AbpBackgroundTasksExceptionHandlingModule.cs new file mode 100644 index 000000000..716c72f8c --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/AbpBackgroundTasksExceptionHandlingModule.cs @@ -0,0 +1,10 @@ +using LINGYUN.Abp.ExceptionHandling; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.BackgroundTasks.ExceptionHandling; + +[DependsOn(typeof(AbpExceptionHandlingModule))] +public class AbpBackgroundTasksExceptionHandlingModule : AbpModule +{ + +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/JobExceptionNotifier.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/JobExceptionNotifier.cs new file mode 100644 index 000000000..1dda90249 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/JobExceptionNotifier.cs @@ -0,0 +1,76 @@ +using JetBrains.Annotations; +using LINGYUN.Abp.BackgroundTasks.Jobs; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Timing; + +namespace LINGYUN.Abp.BackgroundTasks.ExceptionHandling; + +[Dependency(ReplaceServices = true)] +public class JobExceptionNotifier : IJobExceptionNotifier, ITransientDependency +{ + public const string Prefix = "exception."; + + protected IClock Clock { get; } + protected IJobStore JobStore { get; } + protected IJobScheduler JobScheduler { get; } + + public JobExceptionNotifier( + IClock clock, + IJobStore jobStore, + IJobScheduler jobScheduler) + { + Clock = clock; + JobStore = jobStore; + JobScheduler = jobScheduler; + } + + public virtual async Task NotifyAsync([NotNull] JobExceptionNotificationContext context) + { + var notifyKey = Prefix + SendEmailJob.PropertyTo; + if (context.JobInfo.Args.TryGetValue(notifyKey, out var exceptionTo)) + { + var template = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertyTemplate) ?? ""; + var subject = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertySubject) ?? "From job execute exception"; + var globalContext = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertyContext) ?? "{}"; + var from = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertyFrom) ?? ""; + var culture = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertyCulture) ?? CultureInfo.CurrentCulture.Name; + + var jobId = Guid.NewGuid(); + var jobArgs = new Dictionary + { + { SendEmailJob.PropertyTo, exceptionTo.ToString() }, + { SendEmailJob.PropertySubject, subject }, + { SendEmailJob.PropertyBody, context.Exception.GetBaseException().Message }, + { SendEmailJob.PropertyTemplate, template }, + { SendEmailJob.PropertyContext, globalContext }, + { SendEmailJob.PropertyFrom, from }, + { SendEmailJob.PropertyCulture, culture } + }; + var jobInfo = new JobInfo + { + Id = jobId, + Name = jobId.ToString(), + Group = "ExceptionHandling", + Priority = JobPriority.Normal, + BeginTime = Clock.Now, + Args = jobArgs, + Description = subject.ToString(), + JobType = JobType.Once, + Interval = 5, + MaxCount = 1, + MaxTryCount = 1, + CreationTime = Clock.Now, + Status = JobStatus.None, + Type = DefaultJobNames.SendEmailJob, + }; + + await JobStore.StoreAsync(jobInfo); + + await JobScheduler.TriggerAsync(jobInfo); + } + } +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/FodyWeavers.xml b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/FodyWeavers.xml index ac6b5b292..1715698cc 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/FodyWeavers.xml +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/FodyWeavers.xml @@ -1,3 +1,3 @@ - - + + \ No newline at end of file diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/SendEmailJob.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/SendEmailJob.cs index 765c35db6..0864919bc 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/SendEmailJob.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/SendEmailJob.cs @@ -1,26 +1,76 @@ using System.Threading.Tasks; using Volo.Abp.Emailing; +using Volo.Abp.TextTemplating; +using Volo.Abp.Json; +using System.Collections.Generic; +using System; namespace LINGYUN.Abp.BackgroundTasks.Jobs; public class SendEmailJob : IJobRunnable { public const string PropertyFrom = "from"; + /// + /// 接收者 + /// public const string PropertyTo = "to"; + /// + /// 必须,邮件主体 + /// public const string PropertySubject = "subject"; + /// + /// 消息内容, 文本消息时必须 + /// public const string PropertyBody = "body"; - public const string PropertyIsBodyHtml = "isBodyHtml"; + + /// + /// 发送模板消息 + /// + public const string PropertyTemplate = "template"; + /// + /// 可选, 模板消息中的上下文参数 + /// + public const string PropertyContext = "context"; + /// + /// 可选, 模板消息中的区域性 + /// + public const string PropertyCulture = "culture"; public virtual async Task ExecuteAsync(JobRunnableContext context) { context.TryGetString(PropertyFrom, out var from); var to = context.GetString(PropertyTo); var subject = context.GetString(PropertySubject); - var body = context.GetString(PropertyBody); - context.TryGetJobData(PropertyIsBodyHtml, out var isBodyHtml); var emailSender = context.GetRequiredService(); - await emailSender.QueueAsync(from, to, subject, body, isBodyHtml); + if (context.TryGetString(PropertyTemplate, out var template) && !template.IsNullOrWhiteSpace()) + { + var globalContext = new Dictionary(); + context.TryGetString(PropertyCulture, out var culture); + if (context.TryGetString(PropertyContext, out var globalCtx)) + { + var jsonSerializer = context.GetRequiredService(); + try + { + globalContext = jsonSerializer.Deserialize>(globalCtx); + } + catch { } + } + + var templateRenderer = context.GetRequiredService(); + + var content = await templateRenderer.RenderAsync( + templateName: template, + cultureName: culture, + globalContext: globalContext); + + await emailSender.QueueAsync(from, to, subject, content, true); + return; + } + + var body = context.GetString(PropertyBody); + + await emailSender.QueueAsync(from, to, subject, body, false); } } diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobExecutedEvent.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobExecutedEvent.cs index 09645f246..922eb911c 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobExecutedEvent.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobExecutedEvent.cs @@ -1,4 +1,6 @@ using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; @@ -50,8 +52,9 @@ public class JobExecutedEvent : JobEventBase, ITransientDepend job.Status = JobStatus.Stopped; job.IsAbandoned = true; job.NextRunTime = null; - await RemoveJobAsync(context, job); + // 重试达到上限发布异常通知 + await NotifierAsync(context, job); } } else @@ -75,4 +78,19 @@ public class JobExecutedEvent : JobEventBase, ITransientDepend var jobScheduler = context.ServiceProvider.GetRequiredService(); await jobScheduler.RemoveAsync(jobInfo); } + + private async Task NotifierAsync(JobEventContext context, JobInfo jobInfo) + { + try + { + var notifier = context.ServiceProvider.GetRequiredService(); + var exceptionContext = new JobExceptionNotificationContext(jobInfo, context.EventData.Exception); + + await notifier.NotifyAsync(exceptionContext); + } + catch (Exception ex) + { + Logger.LogWarning($"An exception thow with job exception notify: {ex.Message}"); + } + } } diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj index 1610fecc9..e64223cd1 100644 --- a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj +++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj @@ -50,6 +50,7 @@ + diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs index 1626a8402..2ea812a44 100644 --- a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs +++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs @@ -1,4 +1,5 @@ using LINGYUN.Abp.AuditLogging.Elasticsearch; +using LINGYUN.Abp.BackgroundTasks.ExceptionHandling; using LINGYUN.Abp.BackgroundTasks.Jobs; using LINGYUN.Abp.BackgroundTasks.Quartz; using LINGYUN.Abp.Data.DbMigrator; @@ -45,6 +46,7 @@ namespace LY.MicroService.TaskManagement; typeof(AbpDbFinderMultiTenancyModule), typeof(AbpBackgroundTasksJobsModule), typeof(AbpBackgroundTasksQuartzModule), + typeof(AbpBackgroundTasksExceptionHandlingModule), typeof(TaskManagementApplicationModule), typeof(TaskManagementHttpApiModule), typeof(TaskManagementEntityFrameworkCoreModule),